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();        }    }

矩形计算

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"

布局

 <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>

人生就是一次充满未知的旅行,在乎的是沿途的风景,

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

相关文章:

你感兴趣的文章:

标签云: