Android自定义圆弧进度条(半圆进度条) 圆弧渐变色进度条带指示 圆弧宽高可自由修改
Posted yeziyfx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义圆弧进度条(半圆进度条) 圆弧渐变色进度条带指示 圆弧宽高可自由修改相关的知识,希望对你有一定的参考价值。
首先我们来看下效果图
圆弧高度可以自定义,说明,只有高度设置为宽度的二分之一时,才是半圆,否则就是半圆的一部分,即圆弧。
不只是圆弧是自定的,图中的文字“2”的控件也是自定义的, 下面也会给出源码。
不多说,直接上源码:
圆弧进度条控件:
/** * Created by yfx on 2022/10/11 17:32 * */ public class CircleBarView extends View private Paint rPaint;//绘制矩形的画笔 private Paint progressPaint;//绘制圆弧的画笔 private Paint anchorPaint,anchorBgPaint;//锚点 private float anchorRadius,anchorBgRadius; private int anchorColor,anchorBgColor; private CircleBarAnim anim; private Paint bgPaint;//绘制背景圆弧的画笔 private float progress;//可以更新的进度条数值 private float maxProgress;//进度条最大值 private float progressSweepAngle;//进度条圆弧扫过的角度 private int startAngle;//背景圆弧的起始角度 private float sweepAngle;//背景圆弧扫过的角度 private RectF mRectF;//绘制圆弧的矩形区域 private float barWidth;//圆弧进度条宽度 private int defaultSize;//自定义View默认的宽高 private int[] progressColors;//进度条圆弧颜色 private int bgColor;//背景圆弧颜色 private SweepGradient sweepGradient;//进度条颜色使用渐变色 private LinearGradient linearGradient; private float circleWidth,circleHeight; private float xDiff; public CircleBarView(Context context, AttributeSet attrs) super(context, attrs); init(context,attrs); private void init(Context context,AttributeSet attrs) TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CircleBarView); int color1 = typedArray.getColor(R.styleable.CircleBarView_progress_color1,Color.RED); int color2 = typedArray.getColor(R.styleable.CircleBarView_progress_color2,color1); int color3 = typedArray.getColor(R.styleable.CircleBarView_progress_color3,color2);//写法巧妙 progressColors=new int[]color1,color1,color2,color3;//必须得4个, bgColor = typedArray.getColor(R.styleable.CircleBarView_bg_color,Color.GRAY);//默认为灰色 circleWidth = typedArray.getDimension(R.styleable.CircleBarView_circle_width,dip2px(context,200));//默认为0 circleHeight = typedArray.getDimension(R.styleable.CircleBarView_circle_height,dip2px(context,80));//默认为360 barWidth = typedArray.getDimension(R.styleable.CircleBarView_bar_width,dip2px(context,10));//默认为10dp anchorRadius = typedArray.getDimension(R.styleable.CircleBarView_anchor_radius,dip2px(context,5)); anchorBgRadius = typedArray.getDimension(R.styleable.CircleBarView_anchor_bg_radius,dip2px(context,8.5f)); anchorColor = typedArray.getColor(R.styleable.CircleBarView_anchor_color,Color.RED); anchorBgColor = typedArray.getColor(R.styleable.CircleBarView_anchor_bg_color,Color.GREEN); maxProgress = typedArray.getInt(R.styleable.CircleBarView_progress_max,100); typedArray.recycle();//typedArray用完之后需要回收,防止内存泄漏 rPaint=new Paint(); rPaint.setStyle(Paint.Style.STROKE);//只描边,不填充 rPaint.setColor(Color.RED); progressPaint=new Paint(); progressPaint.setStyle(Paint.Style.STROKE);//只描边,不填充 progressPaint.setStrokeWidth(barWidth); progressPaint.setAntiAlias(true);//设置抗锯齿 progressPaint.setStrokeCap(Paint.Cap.ROUND); //锚点 anchorPaint=new Paint(); anchorPaint.setAntiAlias(true);//设置抗锯齿 anchorPaint.setColor(anchorColor); //锚点背景 anchorBgPaint=new Paint(); anchorBgPaint.setAntiAlias(true);//设置抗锯齿 int a=Color.alpha(anchorBgColor); int r=Color.red(anchorBgColor); int g=Color.green(anchorBgColor); int b=Color.blue(anchorBgColor); LogSuperUtil.i("circle_bar","a="+a+",r="+r+",g="+g+",b="+b); anchorBgPaint.setColor(Color.rgb(r,g,b)); anchorBgPaint.setAlpha(a); /*raw anchorBgPaint.setColor(anchorBgColor); anchorBgPaint.setAlpha(185);*/ anim=new CircleBarAnim(); bgPaint=new Paint(); bgPaint.setStyle(Paint.Style.STROKE); bgPaint.setColor(bgColor); bgPaint.setStrokeWidth(barWidth); bgPaint.setAntiAlias(true); bgPaint.setStrokeCap(Paint.Cap.ROUND); mRectF=new RectF(); // defaultSize=dip2px(context,200); @Override protected void onDraw(Canvas canvas) super.onDraw(canvas); //进度条的总轮廓 canvas.drawArc(mRectF,startAngle,sweepAngle,false,bgPaint); float outCircleRadius=mRectF.width()/2;//带宽度的进度条的中线半径 if(sweepGradient==null) float centerX=(mRectF.left+mRectF.right)/2; float centerY=(mRectF.top+mRectF.bottom)/2; // int rotateDiff=30;//为了解决圆弧开头出的圆角颜色不正常的问题,30度够用了吧 int rotateDegree=startAngle-rotateDiff; float sweepEndPosition=(rotateDiff+sweepAngle*progress/maxProgress*1.0f)/360; LogSuperUtil.i("circle_bar","startAngle="+startAngle+",sweepEndPosition="+sweepEndPosition); float[] positions=0,rotateDiff*1.0f/360,sweepEndPosition,1; sweepGradient = new SweepGradient(centerX,centerY,progressColors,positions); Matrix rotateMatrix = new Matrix(); //设置渐变色 rotateMatrix.setRotate(rotateDegree, centerX, centerY);//180表示从左侧开始往上渐变 sweepGradient.setLocalMatrix(rotateMatrix);//sweepGradient默认是从0度方向开始渐变的,所以要逆转一下。 progressPaint.setShader(sweepGradient); /* if(linearGradient==null) linearGradient = new LinearGradient(0, 0, outCircleRadius*2, 0, progressColors, null, LinearGradient.TileMode.CLAMP); progressPaint.setShader(linearGradient); */ //进度条 canvas.drawArc(mRectF,startAngle,progressSweepAngle,false,progressPaint); float anchorAngle=progressSweepAngle+(startAngle-180); float anchorCoordRedius=outCircleRadius-barWidth/2; double cosValue=Math.cos(Math.toRadians(anchorAngle)); double sinValue=Math.sin(Math.toRadians(anchorAngle)); float diffByAnchor=anchorBgRadius-barWidth/2;//x和y的偏移正好都是这个 //float cx=(float)(outCircleRadius-cosValue*anchorCoordRedius+diffByAnchor); float cx=(float)(outCircleRadius-cosValue*outCircleRadius+anchorBgRadius); //float cy=(float)(outCircleRadius-sinValue*anchorCoordRedius+diffByAnchor); float cy=(float)(outCircleRadius-sinValue*outCircleRadius+anchorBgRadius); canvas.drawCircle(cx-xDiff,cy,anchorRadius,anchorPaint);//锚点小圆 canvas.drawCircle(cx-xDiff,cy,anchorBgRadius,anchorBgPaint);//锚点背景大圆 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) super.onMeasure(widthMeasureSpec, heightMeasureSpec); //int height=measureSize(defaultSize,heightMeasureSpec); //int width=measureSize(defaultSize,widthMeasureSpec); //startAngle是计算出来的,因为弦的这种,没法通过观察直接得出圆弧的起始角度 //通过数学计算得知x //x是圆心(圆弧所在的圆的圆心)到弦(也就是圆弧的底部)的垂直距离 float x=(circleWidth*circleWidth-4*circleHeight*circleHeight)/(8*circleHeight); //画圆弧用到的圆的半径 float r=x+circleHeight; //int r=(int)(circleWidth/2/Math.cos(Math.toRadians(startAngle-180))); //弦长/2/半径=cos(startAngle-180) //(startAngle-180) double asin=Math.asin(circleWidth/2/r); //LogSuperUtil.i("circle_bar","asin="+asin); int a=(int)Math.toDegrees(asin); //LogSuperUtil.i("circle_bar","a="+a); startAngle=180+(90-a); sweepAngle=2*a; //int min=Math.max(width,height);//获取View最短边的长度 int width=(int)(Math.sqrt(Math.pow(r+anchorBgRadius,2)-Math.pow(x,2))*2+0.5f+anchorBgRadius);//圆弧的宽度 width=(int)(2*(circleWidth/2+anchorBgRadius)+0.5f); int height=(int)(circleHeight+anchorBgRadius+0.5f+anchorBgRadius); //height=width; xDiff=r-circleWidth/2;//画布是从最左边开始画圆且显示的,不偏移的话,显示的效果不对。 LogSuperUtil.i("circle_bar","xDiff="+xDiff); setMeasuredDimension(width,height); if(Math.min(width,height)>=barWidth*2) //这里简单限制了圆弧的最大宽度 //1.mRectF决定着圆画在哪个框框里面 //2.mRectF在当前View中,但不是完全占据当前View //3.弧度的粗细画的时候是均分到圆半径线的两侧的 //4.之所以矩形设置的四个点有偏移,是因为有弧度宽度。 //因为锚点也有宽度,点再次做调整. //mRectF.set(barWidth/2,barWidth/2,min-barWidth/2,min-barWidth/2); float diffByAnchor=anchorBgRadius-barWidth/2;//受锚点影响需要修正的偏移 //是整个圆的矩形,不是弧形区域所在的矩形 mRectF.set(barWidth/2+diffByAnchor-xDiff,barWidth/2+diffByAnchor,barWidth/2+diffByAnchor+2*r-xDiff,barWidth/2+diffByAnchor+2*r); private int measureSize(int defaultSize,int measureSpec) int result=defaultSize; int specMode= MeasureSpec.getMode(measureSpec); int specSize= MeasureSpec.getSize(measureSpec); if(specMode== MeasureSpec.EXACTLY) LogSuperUtil.i("circle_bar","=EXACTLY"); result=specSize; else if(specMode== MeasureSpec.AT_MOST) LogSuperUtil.i("circle_bar","=AT_MOST"); result=Math.min(result,specSize); else LogSuperUtil.i("circle_bar","=defaultSize"); return result; private TextView textView; private OnAnimationListener onAnimationListener; public class CircleBarAnim extends Animation public CircleBarAnim() @Override protected void applyTransformation(float interpolatedTime, Transformation t) super.applyTransformation(interpolatedTime, t); progressSweepAngle=interpolatedTime*sweepAngle*progress/maxProgress;//这里计算进度条的比例 postInvalidate(); if(textView!=null&&onAnimationListener!=null) textView.setText(onAnimationListener.howToChangeText(interpolatedTime,progress,maxProgress)); /** * 设置显示文字的TextView * @param textView */ public void setTextView(TextView textView) this.textView=textView; /* * circleBarView.setOnAnimationListener(new CircleBarView.OnAnimationListener() @Override public String howToChangeText(float interpolatedTime, float progressNum, float maxNum) DecimalFormat decimalFormat=new DecimalFormat("0.00"); String s = decimalFormat.format(interpolatedTime * progressNum / maxNum * 100) + "%"; return s; ); public interface OnAnimationListener /** * 如何处理要显示的文字内容 * @param interpolatedTime 从0渐变成1,到1时结束动画 * @param progressNum 进度条数值 * @param maxNum 进度条最大值 * @return */ String howToChangeText(float interpolatedTime, float progressNum, float maxNum); //写个方法给外部调用,用来设置动画时间 public void setProgress(float progress,int time) anim.setDuration(time); this.startAnimation(anim); this.progress=progress; public static int dip2px(Context context,float dpValue) float scale=context.getResources().getDisplayMetrics().density; return (int)(dpValue*scale+0.5f); public static int px2dip(Context context,float pxValue) float scale=context.getResources().getDisplayMetrics().density; return (int)(pxValue/scale+0.5f); /** * //extraDistance比较小时,TextView离圆弧很近,是正常,因为TextView是从其自身的左上角开始渲染。 * @param sweepAnglePercent * @param extraDistance * @return */ public float getAngleX(float sweepAnglePercent,int extraDistance) float outCircleRadius=mRectF.width()/2+barWidth/2;//带宽度的进度条的外圆半径 float diffByAnchor=anchorBgRadius-barWidth/2;//x和y的偏移正好都是这个 float x=(float)(outCircleRadius+diffByAnchor-Math.cos(Math.toRadians(startAngle-180+sweepAnglePercent*sweepAngle))*(outCircleRadius+dip2px(getContext(),extraDistance))-xDiff); return x; private static final String TAG="circle_bar"; /** * 在当前View中的y坐标 * (注意,TextView渲染的时候,这个坐标是作为TextView控件的左上角进行渲染。 * 所以,extraDistance小的话,显示的结果TextView可能还在当前View的内部呢,但TextView的左上角是在圆外部的。 * @param sweepAnglePercent * @param extraDistance 从外圆算的往外扩展的距离,不是从锚点背景边缘往外扩展。 * @return */ public float getAngleY(float sweepAnglePercent,int extraDistance) float outCircleRadius=mRectF.width()/2+barWidth/2;//带宽度的进度条的外圆半径 float diffByAnchor=anchorBgRadius-barWidth/2;//x和y的偏移正好都是这个 float coordA=startAngle-180+sweepAnglePercent*sweepAngle; LogSuperUtil.i("circle_bar","coordA="+coordA); float coordY=(float)Math.sin(Math.toRadians(coordA))*(outCircleRadius+dip2px(getContext(),extraDistance)); LogSuperUtil.i("circle_bar","coordY="+coordY); float tempR=outCircleRadius+diffByAnchor; LogSuperUtil.i("circle_bar","tempR="+tempR+",="+circleWidth);//CircleWidth是圆弧宽度 LogSuperUtil.i("circle_bar","mRectF.width()/2="+mRectF.width()/2); float y=(float) (tempR-coordY); return y;
然后,是那个背景是圆(圆有渐变色和内间距)的文字控件的源码:
/**
* 表示用户等级的文字,可以设置背景色、圆环色、圆弧与背景的内间距
* Created by yfx on 2022/10/20 16:36
*/
public class CircleBarTextView extends AppCompatTextView
private Paint mPaintBg;
private Paint mPaintRing;
private float mRadiusBg;
private float mRadiusRing;
private float mRingStrokeWidth;
private float mPaddingRing2Bg;
private boolean mIsBgShow;
private boolean mIsRingShow;
private int[] ringColors;//进度条圆弧颜色
private int[] bgColors;//
private LinearGradient linearGradientRing;
private LinearGradient linearGradientBg;
public CircleBarTextView(Context context, @Nullable AttributeSet attrs)
super(context, attrs);
init(context,attrs);
private void init(Context context,AttributeSet attrs)
TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CircleTextView);
int ringColor1 = typedArray.getColor(R.styleable.CircleTextView_ringColor1,Color.RED);
int ringColor2 = typedArray.getColor(R.styleable.CircleTextView_ringColor2,ringColor1);
//int color3 = typedArray.getColor(R.styleable.CircleTextView_ringColor3,color2);//写法巧妙
ringColors=new int[]ringColor1,ringColor2;
int bgColor1 = typedArray.getColor(R.styleable.CircleTextView_bgColor1,Color.RED);
int bgColor2 = typedArray.getColor(R.styleable.CircleTextView_bgColor2,bgColor1);
//int color3 = typedArray.getColor(R.styleable.CircleTextView_ringColor3,color2);//写法巧妙
bgColors=new int[]bgColor1,bgColor2;
mPaddingRing2Bg = typedArray.getDimension(R.styleable.CircleTextView_paddingRing2Bg,0);//写法巧妙
mRingStrokeWidth = typedArray.getDimension(R.styleable.CircleTextView_ringStrokeWidth,0);//写法巧妙
//
mPaintBg=new Paint();
mPaintBg.setColor(bgColor1);
mPaintBg.setStyle(Paint.Style.FILL);
mPaintBg.setAntiAlias(true);
//
mPaintRing=new Paint();
mPaintBg.setColor(ringColor1);
mPaintRing.setStyle(Paint.Style.STROKE);
mPaintRing.setStrokeWidth(mRingStrokeWidth);
mPaintRing.setAntiAlias(true);
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/*
int width=mRadiusRing*2;
int height=mRadiusRing*2;
setMeasuredDimension(width,height);*/
@Override
protected void onDraw(Canvas canvas)
float cx=getWidth()/2;
float cy=getWidth()/2;
mRadiusRing=getWidth()/2-mRingStrokeWidth/2;
mRadiusBg=mRadiusRing-mPaddingRing2Bg-mRingStrokeWidth/2;
//渐变色设置
if(linearGradientRing==null)
float r=mRadiusRing+mRingStrokeWidth/2;
float x0=(float)(r-r/Math.sqrt(2));
float y0=(float)(r+r/Math.sqrt(2));
float x1=(float)(r+r/Math.sqrt(2));
float y1=(float)(r-r/Math.sqrt(2));
linearGradientRing = new LinearGradient(x0, y0, x1, y1, ringColors,
null, LinearGradient.TileMode.CLAMP);
mPaintRing.setShader(linearGradientRing);
if(linearGradientBg==null)
float r=mRadiusRing+mRingStrokeWidth/2;//还是根据最大圆来计算
float x0=r-mRingStrokeWidth-mPaddingRing2Bg;
float y0=r;
float x1=r+mRadiusBg;
float y1=r;
//左下到右上的线性渐变
linearGradientBg = new LinearGradient(x0, y0, x1, y1, bgColors,
null, LinearGradient.TileMode.CLAMP);
mPaintBg.setShader(linearGradientBg);
if(mIsBgShow)
canvas.drawCircle(cx,cy,mRadiusBg,mPaintBg);
if(mIsRingShow)
canvas.drawCircle(cx,cy,mRadiusRing,mPaintRing);
//canvas.drawtext
super.onDraw(canvas);
public static int dip2px(Context context,float dpValue)
float scale=context.getResources().getDisplayMetrics().density;
return (int)(dpValue*scale+0.5f);
public void setBgShow(boolean isShow)
mIsBgShow=isShow;
postInvalidate();
public void setRingShow(boolean isShow)
mIsRingShow=isShow;
postInvalidate();
自定义属性:
<declare-styleable name="CircleBarView"> <attr name="progress_color1" format="reference|color"></attr> <attr name="progress_color2" format="reference|color"></attr> <attr name="progress_color3" format="reference|color"></attr> <attr name="bg_color" format="color"></attr> <attr name="bar_width" format="dimension"></attr> <attr name="circle_width" format="dimension"></attr><!--背景圆弧宽度 --> <attr name="circle_height" format="dimension"></attr><!--背景圆弧高度 --> <attr name="anchor_radius" format="dimension"></attr> <attr name="anchor_bg_radius" format="dimension"></attr> <attr name="anchor_color" format="reference|color"></attr> <attr name="anchor_bg_color" format="reference|color"></attr> <attr name="progress_max" format="integer"></attr> </declare-styleable> <declare-styleable name="CircleTextView"> <attr name="paddingRing2Bg" format="dimension"></attr> <attr name="ringStrokeWidth" format="dimension"></attr> <attr name="ringColor1" format="reference|color"></attr> <attr name="ringColor2" format="reference|color"></attr> <attr name="bgColor1" format="reference|color"></attr> <attr name="bgColor2" format="reference|color"></attr> </declare-styleable>
文字的位置需要处理,使用时有几个细节需要注意,我们下篇再具体介绍。
紧急联系请家伟信ye10612424091
Android 自定义漂亮的圆形进度条
这几天对Android中实现画圆弧及圆弧效果中所实现的效果进行了修改,改为进度圆心进度条,效果如图所示
attrs.xml
源码下载:http://download.csdn.net/detail/nainai007/6554501
TasksCompletedView.java 代码如下
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.view.View;
import com.snailws.taskscompleted.R;
/**
* @author naiyu(http://snailws.com)
* @version 1.0
*/
public class TasksCompletedView extends View {
// 画实心圆的画笔
private Paint mCirclePaint;
// 画圆环的画笔
private Paint mRingPaint;
// 画字体的画笔
private Paint mTextPaint;
// 圆形颜色
private int mCircleColor;
// 圆环颜色
private int mRingColor;
// 半径
private float mRadius;
// 圆环半径
private float mRingRadius;
// 圆环宽度
private float mStrokeWidth;
// 圆心x坐标
private int mXCenter;
// 圆心y坐标
private int mYCenter;
// 字的长度
private float mTxtWidth;
// 字的高度
private float mTxtHeight;
// 总进度
private int mTotalProgress = 100;
// 当前进度
private int mProgress;
public TasksCompletedView(Context context, AttributeSet attrs) {
super(context, attrs);
// 获取自定义的属性
initAttrs(context, attrs);
initVariable();
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.TasksCompletedView, 0, 0);
mRadius = typeArray.getDimension(R.styleable.TasksCompletedView_radius, 80);
mStrokeWidth = typeArray.getDimension(R.styleable.TasksCompletedView_strokeWidth, 10);
mCircleColor = typeArray.getColor(R.styleable.TasksCompletedView_circleColor, 0xFFFFFFFF);
mRingColor = typeArray.getColor(R.styleable.TasksCompletedView_ringColor, 0xFFFFFFFF);
mRingRadius = mRadius + mStrokeWidth / 2;
}
private void initVariable() {
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(mCircleColor);
mCirclePaint.setStyle(Paint.Style.FILL);
mRingPaint = new Paint();
mRingPaint.setAntiAlias(true);
mRingPaint.setColor(mRingColor);
mRingPaint.setStyle(Paint.Style.STROKE);
mRingPaint.setStrokeWidth(mStrokeWidth);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setARGB(255, 255, 255, 255);
mTextPaint.setTextSize(mRadius / 2);
FontMetrics fm = mTextPaint.getFontMetrics();
mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
}
@Override
protected void onDraw(Canvas canvas) {
mXCenter = getWidth() / 2;
mYCenter = getHeight() / 2;
canvas.drawCircle(mXCenter, mYCenter, mRadius, mCirclePaint);
if (mProgress > 0 ) {
RectF oval = new RectF();
oval.left = (mXCenter - mRingRadius);
oval.top = (mYCenter - mRingRadius);
oval.right = mRingRadius * 2 + (mXCenter - mRingRadius);
oval.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);
canvas.drawArc(oval, -90, ((float)mProgress / mTotalProgress) * 360, false, mRingPaint); //
// canvas.drawCircle(mXCenter, mYCenter, mRadius + mStrokeWidth / 2, mRingPaint);
String txt = mProgress + "%";
mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());
canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter + mTxtHeight / 4, mTextPaint);
}
}
public void setProgress(int progress) {
mProgress = progress;
// invalidate();
postInvalidate();
}
}
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TasksCompletedView">
<attr name="radius" format="dimension"/>
<attr name="strokeWidth" format="dimension"/>
<attr name="circleColor" format="color"/>
<attr name="ringColor" format="color"/>
</declare-styleable>
</resources>
源码下载:http://download.csdn.net/detail/nainai007/6554501
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
以上是关于Android自定义圆弧进度条(半圆进度条) 圆弧渐变色进度条带指示 圆弧宽高可自由修改的主要内容,如果未能解决你的问题,请参考以下文章