Android自定义View——动态进度条

愿君学长松,慎勿作桃李。这篇文章主要讲述Android自定义View——动态进度条相关的知识,希望能为你提供帮助。
效果图:

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 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); }@ Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth= mHeight= getScreenWidth()*2/3; setMeasuredDimension(mWidth,mHeight); }@ Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制底层圆弧, 矩形的具体计算见图片 canvas.drawArc(new RectF(mProgressWidth+ mDistanceItem+ mLongItem,mProgressWidth+ mDistanceItem+ mLongItem,mWidth-mProgressWidth-mDistanceItem-mLongItem,mHeight-mProgressWidth-mDistanceItem-mLongItem),0,360,true,mPaintbg); //绘制边缘线 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,10,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+ mDistanceItem+ mLongItem,mProgressWidth+ mDistanceItem+ mLongItem,mWidth-mProgressWidth-mDistanceItem-mLongItem,mHeight-mProgressWidth-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); }/** * 设置动画 * @ 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() { @ Override public void onAnimationUpdate(ValueAnimator valueAnimator) { currentvalue= (float) valueAnimator.getAnimatedValue(); curvalue= curvalue/10; invalidate(); } }); animator.start(); } private int dip2px(float dip){ float density= getContext().getResources().getDisplayMetrics().density; return (int)(dip*density+ 0.5f); } } private int getScreenWidth(){ WindowManager manager= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); Display display= manager.getDefaultDisplay(); if(Build.VERSION.SDK_INT> = 13){ Point point= new Point(); display.getSize(point); return point.x; }else { return display.getWidth(); } }

矩形计算
Android自定义View——动态进度条

文章图片

Activity调用
@ Override protected 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() { @ Override public 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"

【Android自定义View——动态进度条】布局
< 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" > < Button android:id= " @ + id/bt1" android:layout_width= " wrap_content" android:layout_height= " wrap_content" android:text= " start1" /> < com.demo.demo.networkdemo.colorprogressbar.widget.ColorProgressBar android: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>


    推荐阅读