Android 自定义view实现动态进度条效果图:
这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧、顶部、右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这个过程还是有点曲折的,不过还是觉得收获挺多的。比如通动画来进行动态的展示(之前做的都是通过Handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画部分就可以了。不多说了,上代码了。
代码
自定义View
public class ColorProgressBar extends View{//下面这两行在本demo中没什么用,只是前几天看别人的代码时学到的按一定尺寸,设置其他尺寸的方式,自动忽略或者学习一下也不错//private int defaultStepIndicatorNum= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40,getResources().getDisplayMetrics());//int mCircleRadius=0.28f*defaultStepIndicatorNum;//布局的宽高private int mWidth;private int mHeight;//直径private int mDiameter=500;//底层圆画笔private Paint mPaintbg;//顶层圆的画笔private Paint mPaintft;//周围线的画笔private Paint mPaintLine;//外层线条的长度private int mLongItem=dip2px(20);//线条与圆的间距private int mDistanceItem=dip2px(10);//进度条的最大宽度(取底层进度条与顶层进度条宽度最大的)private int mProgressWidth;//底层圆的颜色private int mBackColor;//顶层圆的颜色private int mFrontColor;//底层圆、顶层圆的宽度private float mBackWidth;private float mFrontWidth;//设置进度private float currentvalue;//通过动画演示进度private ValueAnimator animator;private int curvalue;public ColorProgressBar(Context context) {this(context,null,0);}public ColorProgressBar(Context context, AttributeSet attrs) {this(context, attrs,0);}public ColorProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.ColorProgressBar);mBackColor= ta.getColor(R.styleable.ColorProgressBar_back_color, Color.BLACK);mFrontColor=ta.getColor(R.styleable.ColorProgressBar_front_color,mBackColor);mBackWidth=ta.getDimension(R.styleable.ColorProgressBar_back_width,dip2px(10));mFrontWidth=ta.getDimension(R.styleable.ColorProgressBar_front_width,dip2px(10));mProgressWidth=mBackWidth>mFrontWidth?(int)mBackWidth:(int)mFrontWidth;//注意释放资源ta.recycle();init();}/** * 都是画笔初始化 */private void init() {mPaintbg=new Paint(Paint.ANTI_ALIAS_FLAG);mPaintbg.setStrokeWidth(mProgressWidth);mPaintbg.setColor(mBackColor);mPaintbg.setStrokeCap(Paint.Cap.ROUND);mPaintbg.setStyle(Paint.Style.STROKE);mPaintft=new Paint(Paint.ANTI_ALIAS_FLAG);mPaintft.setColor(mFrontColor);mPaintft.setStyle(Paint.Style.STROKE);mPaintft.setStrokeWidth(mFrontWidth);mPaintft.setStrokeCap(Paint.Cap.ROUND);mPaintLine=new Paint(Paint.ANTI_ALIAS_FLAG);mPaintLine.setColor(Color.BLACK);mPaintLine.setStrokeWidth(5);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 宽度=高度=(长指针+指针与圆盘的间距+进度条的粗细+半径)*2Log.e("测量数据","LongItem:"+mLongItem+"mDistanceItem:"+mDistanceItem+"mProgressWidth:"+mProgressWidth+"mDiameter:"+mDiameter/2);mWidth=(int)2*(mLongItem+mDistanceItem+mProgressWidth*2+mDiameter/2);mHeight=(int)2*(mLongItem+mDistanceItem+mProgressWidth*2+mDiameter/2);Log.e("自定义View","高度"+mHeight+"宽度"+mWidth);setMeasuredDimension(mWidth,mHeight);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制底层圆弧,矩形的具体计算见图片canvas.drawArc(new RectF(mProgressWidth/2+mDistanceItem+mLongItem,mProgressWidth/2+mDistanceItem+mLongItem,mWidth-mProgressWidth/2-mDistanceItem-mLongItem,mHeight-mProgressWidth/2-mDistanceItem-mLongItem),0,360,true,mPaintbg);//SweepGradient gradient=new SweepGradient();//绘制边缘线canvas.save();canvas.rotate(144,mWidth/2,mHeight/2);for(int i=0;i<=30;i++){canvas.rotate(-9,mWidth/2,mHeight/2);if(i%5==0){canvas.drawLine(mWidth/2,5,mWidth/2,mLongItem,mPaintbg);}else {canvas.drawLine(mWidth/2,25,mWidth/2,mLongItem,mPaintLine);}}canvas.restore();//给画笔设置渐变SweepGradient sweepGradient=new SweepGradient(mWidth/2,mHeight/2,Color.RED,Color.YELLOW);mPaintft.setShader(sweepGradient);//绘制顶层圆弧,currentvalue在改变时呈现动态效果canvas.drawArc(new RectF(mProgressWidth/2+mDistanceItem+mLongItem,mProgressWidth/2+mDistanceItem+mLongItem,mWidth-mProgressWidth/2-mDistanceItem-mLongItem,mHeight-mProgressWidth/2-mDistanceItem-mLongItem),135,currentvalue,false,mPaintft);mPaintft.setTextSize(100);mPaintft.setTextAlign(Paint.Align.CENTER);//绘制文本canvas.drawText(String.format("%.0f",currentvalue),mWidth/2,mHeight/2+50,mPaintft);invalidate();}/** * 设置动画 * @param value */public void setCurrentValue(float value){//currentvalue=value;animator=ValueAnimator.ofFloat(currentvalue,value);animator.setDuration(3000);animator.setTarget(currentvalue);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {currentvalue= (float) valueAnimator.getAnimatedValue();curvalue=curvalue/10;}});animator.start();}private int dip2px(float dip){float density=getContext().getResources().getDisplayMetrics().density;return (int)(dip*density+0.5f);}}
矩形计算

Activity调用
@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.colorprogressbar);mBtStart1= (Button) findViewById(R.id.bt1);bar1= (ColorProgressBar) findViewById(R.id.cp1);mBtStart1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {bar1.setCurrentValue(270);}});}
自定义属性
<declare-styleable name="ColorProgressBar"><attr name="back_color" format="color"></attr><attr name="front_color" format="color"></attr><attr name="back_width" format="dimension"></attr><attr name="front_width" format="dimension"></attr></declare-styleable>
布局
注意:为了使用自定义属性需要添加一行代码(AS)
xmlns:app=http://schemas.android.com/apk/res-auto
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><Buttonandroid:id="@+id/bt1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="start1"/><com.demo.demo.networkdemo.colorprogressbar.widget.ColorProgressBarandroid:id="@+id/cp1"android:layout_width="232dp"android:layout_height="match_parent"android:layout_gravity="center_horizontal"app:back_color="@color/colorPrimary"app:front_color="@color/colorAccent"android:background="@mipmap/ic_launcher"/></LinearLayout>
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!