我的Android进化论——[View自定义] 画双环进度条

正在学习中,大神请指教微笑微笑


最近需要双环形进度条,就长下面这样:


(为毛贴图这么不清晰啊...)


于是,就练习了下简单的自定义view。

虽然很简单,但是纪录一下。

代码如下,注释很详细

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 双环进度条
 */
public class ArcProgressView extends View {

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

    public ArcProgressView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ArcProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private Thread animThread;  //动画线程

    //画笔
    private Paint paint;
    //背景色,外环颜色,内环颜色
    private int bgColor = 0x00000000, outerColor = 0xff29b6f6, innerColor = 0xff00a0e8;
    //环的宽度
    private int strokeWidth = 8;
    //内环占外环的比例
    private float percent = 0f;
    //外环进度,内环进度(=360时没有动画,此处外环无动画效果)
    private float outerAngle = 360, innerAngle;

    public void setParams(float percent) {
        setParams(bgColor, outerColor, innerColor, strokeWidth, percent);
    }

    public void setParams(int innerColor, int strokeWidth, float percent) {
        setParams(bgColor, outerColor, innerColor, strokeWidth, percent);
    }

    public void setParams(int bgColor, int outerColor, int innerColor, int strokeWidth, float percent) {
        this.bgColor = bgColor;
        this.outerColor = outerColor;
        this.innerColor = innerColor;
        this.strokeWidth = strokeWidth;
        this.percent = Math.min(percent, 1.0f);

        resetParam();  //重置参数
        postInvalidate();
    }

    private void resetParam() {
        animThread = null;  //动画县城置空
        innerAngle = 0;  //内环初始值为0
        paint = getPaint();  //重置画笔
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (paint == null) {
            return;
        }
        //动画线程不为空&内环终值不为0时,启动动画
        if (animThread == null && percent > 0) {
            animThread = getThread();
            animThread.start();
        } else {
            //画背景色
            canvas.drawColor(bgColor);
            //获取环的直径
            int maxWidth = Math.min(getWidth(), getHeight());
            //获取环的偏移量
            int xDistance = 0, yDistance = 0;
            if (getWidth() > getHeight()) {
                xDistance = (getWidth() - getHeight()) / 2;
            } else if (getWidth() < getHeight()) {
                yDistance = (getHeight() - getWidth()) / 2;
            }
            //外环
            if (outerAngle <= 360) {
                RectF ovalOuter = new RectF();//RectF对象
                paint.setColor(outerColor);
                //设置环到矩形区域的left\top\right\bottom的距离
                ovalOuter.set(xDistance + strokeWidth, yDistance + strokeWidth, maxWidth - strokeWidth + xDistance, maxWidth - strokeWidth + yDistance);
                //画环:1.环形所占矩形区域;2.起始角度;3.环扫过的角度,顺时针;4.画笔
                canvas.drawArc(ovalOuter, 90, outerAngle, false, paint);    //绘制圆弧
            }
            //内环
            if (innerAngle <= 360 * percent) {
                RectF ovalInner = new RectF(); //RectF对象
                paint.setColor(innerColor);
                //设置内环区域
                ovalInner.set(xDistance + strokeWidth * 1.8f, yDistance + strokeWidth * 1.8f, maxWidth - strokeWidth * 1.8f + xDistance, maxWidth - strokeWidth * 1.8f + yDistance);
                canvas.drawArc(ovalInner, 90, innerAngle, false, paint);    //绘制圆弧
                if (onProgressListener != null) {
                    onProgressListener.onProgress(innerAngle / (360 * percent));
                }
            }
        }
    }

    private Paint getPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(strokeWidth);
        paint.setStyle(Paint.Style.STROKE);
        return paint;
    }

    private Thread getThread() {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                //外环、内环步长
                int outerStep = 10, innerStep = 8;
                //是否过界
                while ((outerAngle < 360) || (innerAngle < 360 * percent)) {
                    outerAngle = Math.min(outerAngle + outerStep, 360);
                    innerAngle = Math.min(innerAngle + innerStep, 360 * percent);
                    postInvalidate();
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    @Override
    protected void onDetachedFromWindow() {
        outerAngle = innerAngle = 99999;  //退出循环
        super.onDetachedFromWindow();
    }

    /**
     * listener
     */
    private OnProgressListener onProgressListener;

    public void setOnProgressListener(OnProgressListener onProgressListener) {
        this.onProgressListener = onProgressListener;
    }

    public interface OnProgressListener {
        /**
         * 可根据画环的进度更新环内的数字
         *
         * @param progress
         */
        void onProgress(float progress);
    }

}

学无止境啊,加油加油~


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值