Android学习笔记——自定义CircleProgressBarView

本文介绍了如何根据鸿洋老师的教程实现一个自定义的CircleProgressBarView,详细讲解了自定义View的四个步骤:定义attrs.xml,获取自定义样式属性,重写onDraw和onMeasure方法,最终达到画出一个可以切换颜色360度旋转的圆形进度条的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 今天又花了一些时间看了鸿洋老师的博客,继续学习了 关于自定义view的相关,这次是实现类似圆形进度条的CircleProgressBarView;

 还是自定义View的四个步骤(温习一下):

1. 在 res/values/ 下写 attrs.xml 文档来定义自定义View的样式;

2. 在自定义view的构造函数中获取自定义样式属性;

3. 重写 onDraw函数;

4. 重写 onMeasure函数;

OK,先 po一张 要实现的View的样子:



对,大概就是这个样子,然后两种颜色切换360度画圆。。


OK,首先 attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="customFirstColor" format="color"/>
    <attr name="customSecondColor" format="color"/>
    <attr name="customCircleWidth" format="dimension"/>
    <attr name="customSpeed" format="integer"/>

    <declare-styleable name="CustomCircleProgressBarView">

        <attr name="customFirstColor"/>
        <attr name="customSecondColor"/>
        <attr name="customCircleWidth"/>
        <attr name="customSpeed"/>

    </declare-styleable>

</resources>

为了实现这样的效果,我们自定义了四个属性:第一圈颜色,第二圈颜色, 圈的宽度以及 画圆的速度。。。感觉自定义view,好的角色拆分很重要啊。。


OK, 然后 第二步:

<pre name="code" class="java">    private int mFirstColor;

    private int mSecondColor;

    private int mCircleWidth;

    private int mSpeed;

    private int mProgress;

    private boolean isNext;

    private Paint mPaint;

    public CustomCircleProgressBarView(Context context){

        this(context , null);
    }

    public CustomCircleProgressBarView(Context context , AttributeSet attrs){

        this(context , attrs , 0);
    }

    public CustomCircleProgressBarView(Context context, AttributeSet attrs, int defStyle){

        super(context, attrs , defStyle);

        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, 
                R.styleable.CustomCircleProgressBarView , defStyle , 0);

        int n = array.getIndexCount();

        for(int i = 0; i< n;i ++){

            int attr = array.getIndex(i);

            switch (attr){

                case R.styleable.CustomCircleProgressBarView_customFirstColor:

                    mFirstColor = array.getColor(attr , Color.BLUE);
                    break;

                case R.styleable.CustomCircleProgressBarView_customSecondColor:

                    mSecondColor = array.getColor(attr , Color.BLUE);
                    break;

                case R.styleable.CustomCircleProgressBarView_customCircleWidth:

                    mCircleWidth = array.getDimensionPixelSize(attr , 
                            (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP 
                                    ,20, getResources().getDisplayMetrics()));
                    break;

                case R.styleable.CustomCircleProgressBarView_customSpeed:

                    mSpeed = array.getInt(attr , 20);
                    break;
            }


        }

        array.recycle();

        mPaint = new Paint();

        new Thread(new Runnable() {
            @Override
            public void run() {

                while(true){

                    mProgress++;

                    if(mProgress == 360){

                        mProgress = 0;

                        isNext = ! isNext;
                    }

                    postInvalidate();

                    try {

                        Thread.sleep(mSpeed);

                    }catch (InterruptedException e){

                        e.printStackTrace();

                    }
                }
            }
        }).start();
    }



在构造函数里获取 自定义样式 属性,然后 开线程 用于 绘制策略。。。 注意 postInvalidate() 和 invalidate()在更新 UI 时的区别。。这里在新线程中做更新,只能用postInvalidate()。。。

然后 重写 onDraw():

    @Override
    protected void onDraw(Canvas canvas) {

       int centre = getWidth() / 2;

       int radius = centre - mCircleWidth / 2;

       mPaint.setStrokeWidth(mCircleWidth);

       mPaint.setAntiAlias(true);

       mPaint.setStyle(Paint.Style.STROKE);

       RectF oval = new RectF(centre - radius , centre - radius, centre + radius, centre + radius);

       if(!isNext){

           mPaint.setColor(mFirstColor);

           canvas.drawCircle(centre, centre, radius, mPaint);

           mPaint.setColor(mSecondColor);

           canvas.drawArc(oval , -90 , mProgress , false, mPaint);

       }else{

           mPaint.setColor(mSecondColor);

           canvas.drawCircle(centre , centre , radius , mPaint);

           mPaint.setColor(mFirstColor);

           canvas.drawArc(oval , -90 , mProgress , false, mPaint);

       }
    }

OK, 最后在 所需要用到改 自定义View的布局文件中 定义就好:

    <com.example.dxdrush.customcircleprogressbarviewdemo.views.CustomCircleProgressBarView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        custom:customFirstColor="#22ff22"
        custom:customSecondColor="#ff22ff"
        custom:customCircleWidth="20dp"
        custom:customSpeed="20"
        />









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值