自定义控件之动态进度View

来源:互联网 发布:骚男的衣服淘宝店 编辑:程序博客网 时间:2024/06/08 03:21

效果

首先看一下效果
这里写图片描述

实现思路

仔细看这个效果,将整个过程一个一个的分解:

分解    1.画一个箭头    2.箭头渐变    3.弹出圆球    4.画圆弧    5.画勾每个过程通过一个进度百分比来记录进度,然后就是按顺序一个个的画出来
public class LoadingView extends View {    // 开始绘制的标志    private boolean mCanDraw = true;    private boolean mIsStart = true;    private int mDrawUpLinePercent;    private int mDrawOnLinePercent;    private int mOutPointPercent;    private int mDrawGouPercent;    private int mWidth = 0;    private int mheight = 0;    // 圆心半径    private float mCircleX = 0;    private float mCircleY = 0;    private float mRedius = 80;    private int mOuterCircleStrokeWidth = 10;    private Paint mPaint;    private RectF mRectF;    public LoadingView(Context context) {        this(context, null);    }    public LoadingView(Context context, AttributeSet attrs) {        super(context, attrs);        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setStrokeWidth(mOuterCircleStrokeWidth);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setColor(Color.parseColor("#44FFFFFF"));    }    @Override    protected void onDraw(Canvas canvas) {        // 获取圆心        mCircleX = mWidth / 2;        mCircleY = mheight / 2;        // 这个path一定只能在这里初始化        Path path = new Path();        mRectF = new RectF(mCircleX - mRedius, mCircleY - mRedius, mCircleX + mRedius, mCircleY + mRedius);        // 绘制外圆        mPaint.setColor(Color.parseColor("#44FFFFFF"));        canvas.drawCircle(mCircleX, mCircleX, mRedius, mPaint);        if (mCanDraw) {            mIsStart = true;            mPaint.setColor(Color.WHITE);            if (mDrawUpLinePercent < 95) {                // 绘制竖线                float temp = (mCircleY / 4) * mDrawUpLinePercent / 100;                canvas.drawLine(mCircleX, mCircleY * 3 / 4 + temp,                        mCircleX, mCircleY * 5 / 4 - temp, mPaint);                // 竖线变化的时候 箭头一直存在                path.moveTo(mCircleX * 3 / 4, mCircleY);                path.lineTo(mCircleX, mCircleY * 5 / 4);                path.lineTo(mCircleX * 5 / 4, mCircleY);                canvas.drawPath(path, mPaint);                mDrawUpLinePercent += 5;            } else {                // path变成直线                if (mDrawOnLinePercent < 100) {                    // 箭头变形                    path.moveTo(mCircleX * 3 / 4, mCircleY);                    float temp = (mCircleY / 4) * mDrawOnLinePercent / 100;                    path.lineTo(mCircleX, mCircleY * 5 / 4 - temp);                    path.lineTo(mCircleX * 5 / 4, mCircleY);                    canvas.drawPath(path, mPaint);                    mDrawOnLinePercent += 5;                    // 圆心一直存在                    canvas.drawCircle(mCircleX, mCircleY, 2.5f, mPaint);                } else {                    // 将点弹出圆外                    if (mOutPointPercent < 100) {                        float temp = mRedius * mOutPointPercent / 100;                        canvas.drawCircle(mCircleX, mCircleY - temp, 2.5f, mPaint);                        mOutPointPercent += 5;                        //弹出圆外的过程中,直线是一直存在的                        canvas.drawLine(mCircleX * 3 / 4, mCircleY, mCircleX * 5 / 4, mCircleY, mPaint);                        mOutPointPercent += 5;                    } else {                        if (mDrawGouPercent < 100) {                            // 同时画勾                            path.moveTo(mCircleX * 3 / 4, mCircleY);                            float t = (mCircleY / 4) * mDrawGouPercent / 100;                            path.lineTo(mCircleX, mCircleY + t);                            path.lineTo(mCircleX * 5 / 4, mCircleY);                            canvas.drawPath(path, mPaint);                            // 画圆弧                            mPaint.setStrokeWidth(mOuterCircleStrokeWidth);                            float temp = (mDrawGouPercent / 100f) * 360;                            canvas.drawArc(mRectF, 270, -temp, false, mPaint);                            mDrawGouPercent += 5;                        } else {                            // 绘制最终的圆                            mPaint.setColor(Color.WHITE);                            canvas.drawCircle(mCircleX, mCircleY, mRedius, mPaint);                            // 绘制最终的勾                            path.moveTo(mCircleX * 3 / 4, mCircleY);                            path.lineTo(mCircleX, mCircleY * 5 / 4);                            path.lineTo(mCircleX * 5 / 4, mCircleY * 4 / 5);                            canvas.drawPath(path, mPaint);                            // 绘制完成                            mCanDraw = false;                        }                    }                }            }        } else {            // 绘制最终的圆            mPaint.setColor(Color.WHITE);            canvas.drawCircle(mCircleX, mCircleY, mRedius, mPaint);            // 绘制最终的勾            path.moveTo(mCircleX * 3 / 4, mCircleY);            path.lineTo(mCircleX, mCircleY * 5 / 4);            path.lineTo(mCircleX * 5 / 4, mCircleY * 4 / 5);            canvas.drawPath(path, mPaint);            mIsStart = false;            // 绘制静态箭头//            canvas.drawLine(mCircleX, mCircleY * 3 / 4,//                    mCircleX, mCircleY * 5 / 4, mPaint);////            path.moveTo(mCircleX * 3 / 4, mCircleY);//            path.lineTo(mCircleX, mCircleY * 5 / 4);//            path.lineTo(mCircleX * 5 / 4, mCircleY);//            canvas.drawPath(path, mPaint);        }        if (mIsStart) {            postInvalidateDelayed(30);        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int width = MeasureSpec.getSize(widthMeasureSpec);        int height = MeasureSpec.getSize(heightMeasureSpec);        if (widthMode == MeasureSpec.EXACTLY) {            mWidth = width;        } else {            mWidth = 400;        }        if (heightMode == MeasureSpec.EXACTLY) {            mheight = height;        } else {            mheight = 400;        }        // 设置自己的真实大小        setMeasuredDimension(width, height);    }}

踩的坑

这个view我自己调了一下午才调出来,还几次都想放弃,最后还是坚持下来了,给自己点个赞!下面说说我遇到的问题吧:

1.坐标计算不熟悉,花费了很多时间,动手比较少2.这个进度onDraw每次触发的时候,我们希望重新绘制下个画面,然而我在画直线的时候将new Path()放在了全局,相当于每次对这个path对象操作,导致每次onDraw画的直线都在,花了好久才找到原因!3.Paint的一些属性改变之后需要重新设置.
0 0
原创粉丝点击