Android自定义控件之自定义下载progress

一言不合先把代码贴上,具体效果,请自行粘贴后,调用start方法。我这边暂时就不做演示了,有时间添加上

public class CircleProgressView extends View {
    private int mSizeWidth = 200;//默认宽度
    private int mSizeHeight = 200;//默认高度
    private int mWidth;//控件宽
    private int mHeight;//控件高
    private Paint mPaint;
    private int radio;//主体圆半径
    private boolean isDrawing = false;//是否在动画状态
    private int mLinePercent;
    private int mCirclePercent;
    private int mUpPercent;
    private boolean isUpDone;
    private int mShapePercent;
    private int wSpace;//横向padding
    private int hSpace;//竖向padding
    private float mPaintWidth = 8f;//画笔宽度,可调
    private int count = 0;


    public CircleProgressView(Context context) {
        this(context, null);
    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.parseColor("#22ffffff"));
        mPaint.setStrokeWidth(8f);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpeMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpeMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpeMode == MeasureSpec.AT_MOST && heightSpeMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mSizeWidth, mSizeHeight);
        } else if (widthSpeMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mSizeWidth, heightSize);
        } else if (heightSpeMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSize, mSizeHeight);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        wSpace = getPaddingLeft() + getPaddingRight();
        hSpace = getPaddingTop() + getPaddingBottom();
        mWidth = w;
        mHeight = h;
        int viewWidth = mWidth - wSpace;
        int viewHeight = mHeight - hSpace;

        radio = (int) (viewWidth > viewHeight ? (viewHeight / 2 - mPaint.getStrokeWidth()) : (viewWidth / 2 - mPaint.getStrokeWidth()));
        mPaintWidth = mPaintWidth > radio / 10 ? radio / 10 : mPaintWidth;
        Log.i("", "");
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.i("draw", isDrawing + "c:" + count++);
        super.onDraw(canvas);
        canvas.drawColor(Color.parseColor("#aa2a5caa"));
        mPaint.setStrokeWidth(mPaintWidth);
        RectF rectF = new RectF(getCenterLeft(), getCenterTop()
                , getCenterRight(), getCenterBottom());
        Path path = new Path();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.parseColor("#99eeeeee"));
        canvas.drawCircle(getCenterX(),
                getCenterY(), radio, mPaint);
        if (!isDrawing) {
            //绘制静态箭头
            mPaint.setColor(Color.WHITE);
            canvas.drawLine(getCenterX(), getCenterY() - radio / 2, getCenterX(), getCenterY() + radio / 2, mPaint);
            canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint);
            canvas.drawCircle(getCenterX() + radio / 2, getCenterY(), getCircleRadio(), mPaint);
            path.moveTo(getCenterX() - radio / 2, getCenterY());
            path.lineTo(getCenterX(), getCenterY() + radio / 2);
            path.lineTo(getCenterX() + radio / 2, getCenterY());
            canvas.drawPath(path, mPaint);
        } else {
            //开始变形
            mPaint.setColor(Color.WHITE);

            //如果小于95 就继续缩短。 95是微调值 和point大小相等
            if (mLinePercent < 95) {
                //线段逐渐缩短(终点为mWidth/2,mHeight/2)
                float tmp = radio / 2 * mLinePercent / 100;
                canvas.drawLine(getCenterX(), getCenterY() - radio / 2 + tmp, getCenterX(), getCenterY() + radio / 2 - tmp, mPaint);
                mLinePercent += 5;
            } else {
                //path变成直线
                if (mCirclePercent < 100) {
                    canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint);
                    path.moveTo(-radio / 2 + getCenterX(), getCenterY());
                    path.lineTo(getCenterX(), getCenterY() + radio / 2 - mCirclePercent / 100f / 2 * radio);
                    path.lineTo(getCenterX() + radio / 2, getCenterY());
                    canvas.drawCircle(getCenterX() + radio / 2, getCenterY(), getCircleRadio(), mPaint);
                    canvas.drawPath(path, mPaint);
                    mCirclePercent += 5;

                    //在变成直线的过程中这个点一直存在
                    canvas.drawCircle(getCenterX(), getCenterY(), getCircleRadio(), mPaint);
                } else {
                    //绘制把点上弹的直线

                    //画上升的点
                    if (mUpPercent < 100) {

                        //在点移动到圆弧上的时候 线是一直存在的
                        canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint);
                        canvas.drawLine(getCenterX() - radio / 2, getCenterY(), getCenterX() + radio / 2, getCenterY(), mPaint);
                        canvas.drawCircle(getCenterX() + radio / 2, getCenterY(), getCircleRadio(), mPaint);
                        canvas.drawCircle(getCenterX(), getCenterY() - radio * mUpPercent / 100
                                + mPaint.getStrokeWidth(), getCircleRadio(), mPaint);

                        mUpPercent += 5;
                    } else//上升的点最终的位置
                    {
                        canvas.drawCircle(getCenterX(), getCenterY() - radio, getCircleRadio(), mPaint);
//                        canvas.drawPoint(getCenterX(), getCenterY() - radio, mPaint);
                        isUpDone = true;
                    }
                    if (isUpDone)
                        //改变对勾形状
                        if (mShapePercent < 100) {
                            canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint);
                            path.moveTo(getCenterX() - radio / 2, getCenterY());
                            path.lineTo(getCenterX(), getCenterY() + mShapePercent / 100f * radio / 2);
                            path.lineTo(getCenterX() + radio / 2, getCenterY() - mShapePercent / 100f * radio / 2);
                            canvas.drawCircle(getCenterX() + radio / 2, getCenterY() - mShapePercent / 100f * radio / 2, getCircleRadio(), mPaint);
                            canvas.drawPath(path, mPaint);

                            //动态绘制圆形百分比
                            if (mShapePercent < 100) {
                                canvas.drawArc(rectF, 270, -mShapePercent / 100.0f * 360, false, mPaint);
                            }
                            mShapePercent += 5;


                        } else {
                            canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint);
                            //绘制最终的path
                            path.moveTo(getCenterX() - radio / 2, getCenterY());
                            path.lineTo(getCenterX(), getCenterY() + radio / 2);
                            path.lineTo(getCenterX() + radio / 2, getCenterY() - radio / 2);
                            canvas.drawCircle(getCenterX() + radio / 2, getCenterY() - radio / 2, getCircleRadio(), mPaint);
                            canvas.drawPath(path, mPaint);
//                            绘制最终的圆
                            canvas.drawArc(rectF, 270, -360, false, mPaint);
                            isDrawing = false;
                        }
                }
            }
            if (isDrawing)
                postInvalidateDelayed(10);
        }

    }

    private int getCenterY() {
        return (mHeight - hSpace) / 2 + getPaddingTop();
    }

    private int getCenterX() {
        return getPaddingLeft() + (mWidth - wSpace) / 2;
    }

    private int getCenterBottom() {
        return getCenterY() + radio;
    }

    private int getCenterRight() {
        return getCenterX() + radio;
    }

    private int getCenterTop() {
        return getCenterY() - radio;
    }

    private int getCenterLeft() {
        return getCenterX() - radio;
    }

    private float getCircleRadio() {
        return mPaint.getStrokeWidth() / 30f;
    }

    public void start() {
        isDrawing = true;
        isUpDone = false;
        mUpPercent = 0;
        mLinePercent = 0;
        mCirclePercent = 0;
        mShapePercent = 0;
        invalidate();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值