自定义view圆形进度条。

关于自定义view,学习了很长时间中午有进展了
首先自定义view分为两种:1:内部是空的进度条(如图1所示)2:内部是实心的进度条(图2);
首先说一下我的思路吧;
如果是空心的进度条,这就简单了,底部是一个圆形的实心图形1,然后在这个图形的基础上再画实心弧形2;
如果是实心的进度条,这相比于空心进度条就多了两步,也就是在弧形2之后再画一个实心圆3,最后放上text,也就是数字表示的进度条
首先看一下效果图吧。

图1
这里写图片描述

先来讨论一下都要使用到哪些参数,首先图形1的roundRadius(圆的半径),roundColor(圆的颜色),
roundWidth(圆的宽度),图形2的roundProgressColor(圆的颜色)。text的textColor和textSize。
注意:圆1和圆2的半径是相同的,只有颜色不同;然后就是圆3的color和圆1的color是相同的;
private int roundRadius;//圆的半径
private int roundColor;//底层圆的color;
private int roundProgressColor;//上层圆的color;
private int roundWidth;//圆的宽度
private int textSize;//文字的大小
private int textColor;//文字的颜色
private int TYPE ;//是否是实心的
private float degress;//旋转的角度
private float intervalDegress;//每一次转动的角度
private String text; //字体(进度字体)

后面的TYPE ,是判断进度条的类型;degress是转动的总角度;intervalDegress是没刷新一次view要转动的角度;text也就是text进度条的内容了。
然后我们需要计算一下每一次刷新view所转动的角度也就是intervalDegress

   /**
     * 每一次转动的角度
     * @param sumTime 转动360度所需要的总时间(单位:s)
     * @param intervalTime 刷新view的时间间隔(单位:ms)
     */
    public void setDegress(int sumTime, int intervalTime){
        paint = new Paint();
        rectF = new RectF();
        intervalDegress = ((float)(360 * intervalTime)/((float)(sumTime * 1000)));
    }

然后就是我们什么时候停止刷新view呢?也就是什么时候到达360度呢?
终止条件是:总角度大于360度的话,就终止刷新view

    /**
     * 判断如果度数大于360,就停止invalidate();
     * @return ? true 停止 :false 继续
     */
    public boolean getBooleanPaint(){
        if(degress >= 360){
            return true;
        }else{
            return false;
        }
    };

然后计算text的长度:

    /*
    * 计算 字体的长度
     */
    public String getText() {
        text = (int)(degress * 100/360) + "%";
        return text;
    }

然后就是每一次刷新view,也就是重新绘制view

    /**
     * 刷新view,也就是重新绘制view
     */
    public void getPaint(){
        invalidate();
    }

好了准备工作做好了,现在我们需要写draw方法了;
代码示下:

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float width = getMeasuredWidth() / 2;
        float height = getMeasuredHeight() / 2;

        /**
         * 画底层圆
         */
        paint.setColor(roundColor);//设置底层颜色
        paint.setAntiAlias(true);//设置无锯齿
        paint.setStrokeWidth(roundWidth);//设置圆的宽度
        paint.setStyle(Paint.Style.STROKE);//设置填充类型
        rectF.left = width - roundRadius;
        rectF.top = height - roundRadius;
        rectF.right = width + roundRadius;
        rectF.bottom = height + roundRadius;
        canvas.drawOval(rectF, paint);

        paint.setColor(roundProgressColor);
        degress += intervalDegress;//计算总共总共转动的角度
        rectF.left = width - roundRadius;
        rectF.top = height - roundRadius;
        rectF.right = width + roundRadius;
        rectF.bottom = height + roundRadius;
        if (TYPE == 1) {
            //画实心的弧形
            paint.setStyle(Paint.Style.FILL);
            canvas.drawArc(rectF, -90, (int) degress, true, paint);
        } else {
            //空心的弧形
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(rectF, -90, (int) degress, true, paint);
            //画内部圆
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(roundColor);
            rectF.left = width - roundRadius + roundWidth / 2;
            rectF.top = height - roundRadius + roundWidth / 2;
            rectF.right = width + roundRadius - roundWidth / 2;
            rectF.bottom = height + roundRadius - roundWidth / 2;
            canvas.drawOval(rectF, paint);
            /**
             * 放置文字
             */
            paint.setTextSize(textSize);//设置字体的大小
            paint.setColor(textColor);//设置字体的颜色
            float measue = paint.measureText(getText());//计算字体的长度
            canvas.drawText(getText(), width - measue/2,height, paint);
        }

    }

然后就是activity里的设置了

view = (MyViewGroup) findViewById(R.id.myviewgroup);
        view.setRoundRadius(100);
        view.setRoundColor(Color.GREEN);
        view.setRoundProgressColor(Color.BLUE);
        view.setTYPE(2);
        view.setDegress(30,10);//总共30秒,每隔10毫秒刷新一次view
        view.setRoundWidth(5);
        view.setTextColor(Color.WHITE);
        view.setTextSize(30);
        view.getPaint();

最后创建一个定时器,在handler里面更新UI

TimerTask task = new TimerTask() {
            @Override
            public void run() {
                Message msg = new Message();
                msg.arg1 = 1;
                handler.sendMessage(msg);
            }
        };
  timer = new Timer();
  timer.schedule(task,0,10);//每隔10毫秒刷新一次view

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int arg = msg.arg1;
            switch (arg){
                case 1:{
                    /**
                    * 判断条件是否终止
                    */
                    if(view.getBooleanPaint()){
                        timer.cancel();
                    }else{
                        view.getPaint();
                    }
                    break;
                }
            }
        }
    };

这样就行了Ok了,实际上我只是能写出来 但是写文章的话真的写不好,希望我写的这篇菜文能够帮到各位小伙伴

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值