问题
I have a custom progress bar that looks like this:
Here's the .xml code I've used to create it:
background_drawable.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="@dimen/progress_bar_radial_inner_radius"
android:thickness="@dimen/progress_bar_radial_thickness"
android:shape="ring"
android:useLevel="false" >
<solid android:color="@color/main_color_alpha"/>
</shape>
progress_drawable.xml
<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="270">
<shape
android:innerRadius="@dimen/progress_bar_radial_inner_radius"
android:thickness="@dimen/progress_bar_radial_thickness"
android:shape="ring" >
<solid android:color="@color/main_color"/>
</shape>
</rotate>
What I want to get is a round corners for the ring that I use to show progress. Something that would look like this:
Does someone has any idea on how this can be achieved?
回答1:
Well, I searched a lot about that before.
The only solution I found was a library on GitHub check here
回答2:
I was able to achieve this using a layer list, and adding a dot to each side of the line. The first one will be stuck at the top, while the second one will follow the progress as an inset is added inside a rotate element. You will have to adjust it according to the size of your progressbar layout though. Mine is 250dp x 250dp.
progress_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate android:fromDegrees="270" android:toDegrees="270">
<shape
android:innerRadiusRatio="2.55"
android:shape="ring"
android:thickness="15dp"
android:useLevel="true">
<solid android:color="@color/main_color" />
</shape>
</rotate>
</item>
<item android:bottom="211dp">
<shape
android:innerRadiusRatio="1000"
android:shape="ring"
android:thickness="7dp"
android:useLevel="false">
<solid android:color="@color/main_color" />
</shape>
</item>
<item>
<rotate>
<inset android:insetBottom="211dp">
<shape
android:innerRadiusRatio="1000"
android:shape="ring"
android:thickness="7dp"
android:useLevel="false">
<solid android:color="@color/main_color" />
</shape>
</inset>
</rotate>
</item>
</layer-list>
回答3:
Go through this code hope this will help you
>ProgressBarActivity.java
public class ProgressBarActivity extends AppCompatActivity {
private TextView txtProgress;
private ProgressBar progressBar;
private int pStatus = 0;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress);
txtProgress = (TextView) findViewById(R.id.txtProgress);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
new Thread(new Runnable() {
@Override
public void run() {
while (pStatus <= 100) {
handler.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(pStatus);
txtProgress.setText(pStatus + " %");
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pStatus++;
}
}
}).start();
}
}
> activity_progress.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.placio.android.custom_progressbar_circular.MainActivity" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/progress_drawable"
android:secondaryProgress="0" />
<TextView
android:id="@+id/txtProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/progressBar"
android:layout_centerInParent="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</RelativeLayout>
> progress_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="-90"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270" >
回答4:
Ok, the easiest way I've found to do what I want is to draw progress arc on canvas instead of using progress_drawable.xml. Here's my code in case someone has similar issue.
class RadialProgressBar : ProgressBar {
private val thickness = 28f
private val halfThickness = thickness / 2
private val startAngle = 270f
private var boundsF: RectF? = null
private lateinit var paint: Paint
constructor(context: Context?) : super(context) {
init()
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
init()
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
private fun init() {
paint = Paint()
paint.isAntiAlias = true
paint.style = Paint.Style.STROKE
paint.strokeWidth = thickness
paint.strokeCap = Paint.Cap.ROUND
paint.color = ContextCompat.getColor(context, R.color.main_color)
progressDrawable = null
}
override fun draw(canvas: Canvas?) {
super.draw(canvas)
if (boundsF == null) {
boundsF = RectF(background.bounds)
boundsF?.inset(halfThickness, halfThickness)
}
canvas?.drawArc(boundsF, startAngle, progress * 3.60f, false, paint)
}
}
来源:https://stackoverflow.com/questions/52041905/how-to-make-round-corners-for-a-ring-shape-in-android-drawable