自定义圆形进度条

首先在values文件下面建立 attr.xml文件

<resources>

    <!-- 自定义view的相关属性 -->
    <declare-styleable name="CircleProgressBar">
        <attr name="ringColor" format="color" />
        <attr name="ridus" format="dimension" />
        <attr name="ringWidth" format="dimension" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

然后建立自定义类CircleProgressBar

package com.jufan.zhibo.customviewtext;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 按照一定速率转动的圆形进度条
 * Created by LG on 2016/12/15.
 */

public class CircleProgressBar extends View{
    //默认的属性
    private final int DEFAULT_COLOR = Color.BLUE;
    private final float DEFALUE_RADIUS = 20f;
    private final float DEAFULT_RING_WIDTH = 5f;
    private final float DEFAULT_RADIUS = 9.0f;
    private static int DEAFAULTSTYLE = 0;
    private final int DEAFULT_TEXT_SIZE = 25;
    private final int DEFAULT_INCREMENT = 2;
    private final int DEAFULT_GAP_TIME = 20;

    /**
     * 半径
     */
    private float mRadius;

    /**
     * 环的宽度
     */
    private float mRingWidth;

    /**
     * 环的颜色
     */
    private int mRingColor;

    /**
     * 进度字体的大小
     */
    private int mTextSize;

    /**
     * 剩余的画完圆圈的时间
     */
    private int mRemainTimeToComplete;

    /**
     * 进度增量
     */
    private int mIncrement = DEFAULT_INCREMENT;

    /**
     * 增长模式
     */
    public enum incrementMode {
        incrementByTime,
        incrementBy
    }

    /**
     * 画笔
     */
    private Paint mPaint = new Paint();

    /**
     * 当前进度
     */
    private int currentRate;

    /**
     * 上次draw的时间
     */
    private long lastDrawTime;

    /**
     * 中心的坐标
     */
    Point mCenterPoint = new Point();

    /**
     * 刷新的频率
     */
    private int gapTime = 20;

    private int mToRate = 360;

    private DrawThread mDrawThread = new DrawThread();


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

    public CircleProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, DEAFAULTSTYLE);
    }

    public CircleProgressBar(Context context, AttributeSet attrs, int defStyle) {
        //为什么一定要调用super的构造函数?
        super(context, attrs, defStyle);

        //取出各种属性
        TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleProgressBar, defStyle, 0);
        mRadius = attributes.getDimension(R.styleable.CircleProgressBar_ridus, DEFAULT_RADIUS);
        mRingColor = attributes.getColor(R.styleable.CircleProgressBar_ringColor, DEFAULT_COLOR);
        mRingWidth = attributes.getDimension(R.styleable.CircleProgressBar_ringWidth, DEAFULT_RING_WIDTH);
        mTextSize = (int) attributes.getDimension(R.styleable.CircleProgressBar_textSize, DEAFULT_TEXT_SIZE);
        if(mRingWidth > mRadius)
            mRingWidth = mRadius;
//        int n = attributes.getIndexCount();
//        for (int i = 0; i < n; i++) {
//            int attr = attributes.getIndex(i);
//            switch (attr) {
//                case R.styleable.CircleProgressBar_ridus:
//                    mRadius = attributes.getDimension(R.styleable.CircleProgressBar_ridus, DEFAULT_RADIUS);
//                    break;
//                case R.styleable.CircleProgressBar_ringColor:
//                    mRingColor = attributes.getColor(R.styleable.CircleProgressBar_ringColor, DEFAULT_COLOR);
//                    break;
//                default:
//                    break;
//            }
//        }

        setColor(mRingColor);
        attributes.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


        setMinimumHeight((int) (2 * (mRadius + mRingWidth)));
        setMinimumWidth((int) (2 * (mRadius + mRingWidth)));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mCenterPoint.set(getWidth() / 2, getHeight() / 2);
        mPaint.setStrokeWidth(mRingWidth); // 设置圆环的宽度
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStyle(Paint.Style.STROKE); // 设置空心
        RectF oval = new RectF(mRingWidth / 2, mRingWidth / 2, getWidth() - mRingWidth / 2, getHeight() - mRingWidth / 2); // 用于定义的圆弧的形状和大小的界限
        canvas.drawArc(oval, -90, currentRate, false, mPaint);
        Paint textPaint = new Paint();
        textPaint.setTextSize(mTextSize);
        Rect mBound = new Rect();
        String drawText = ((int) (currentRate / 3.6)) + "%";
        textPaint.getTextBounds(drawText, 0, drawText.length(), mBound);
        canvas.drawText(drawText, mCenterPoint.x - mBound.width() / 2, mCenterPoint.y + mBound.height() / 2, textPaint);
    }

    public void setColor(int color) {
        mRingColor = color;
        mPaint.setColor(color);
    }

    public void setTextSize(int textSize) {
        mTextSize = textSize;
        postInvalidate();
    }

    public int getTextSize() {
        return mTextSize;
    }

    public void finish() {
        finish(1);
    }

    public void finish(int duration) {
        int increaseTime = (360 - currentRate) / mIncrement;
        gapTime = (duration / increaseTime > 2) ? increaseTime : 2;
    }

    void setCurrentRate(int toRate) {
        currentRate = toRate;
        postInvalidate();
    }

    void setCurrentRate(int toRate, int duration) {
        int increaseTime = (toRate - currentRate) / mIncrement;
        gapTime = (duration / increaseTime > 2) ? increaseTime : 2;
    }

    void increase(int increment) {
        increase(increment, 1);
    }

    void increase(int increment, int duration) {
        setCurrentRate(increment + currentRate, duration);
    }

    public void speedUp() {
        mIncrement += 2;
        mIncrement = Math.min(mIncrement, 100);
    }

    public void speedDown() {
        mIncrement -= 2;
        mIncrement = Math.max(0, mIncrement);
    }

    public void reStart() {
        currentRate = 0;
        if(!mDrawThread.isAlive()) {
            mDrawThread = new DrawThread();
            mDrawThread.start();
        }
    }

    private class DrawThread extends Thread {
        @Override
        public void run() {
            while (currentRate <= mToRate) {
                setCurrentRate(currentRate);
                try {
                    sleep(gapTime);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                currentRate += mIncrement;
            }
            postInvalidate();
            currentRate = (currentRate > 360) ? 360 : currentRate;
        }
    }
}

在布局文件中调用自定义的控件

     <com.jufan.zhibo.customviewtext.CircleProgressBar
        android:id="@+id/progressBar"
        custom:ridus="30dp"
        custom:ringWidth="5dp"
        custom:ringColor="#ff0000"
        android:layout_width="60dp"
        android:layout_height="60dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="start"
            android:id="@+id/startBtn" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="减速"
            android:id="@+id/stopBtn" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加速"
            android:id="@+id/increaseBtn" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="字体变大"
            android:id="@+id/increaseLittleBtn" />
    </LinearLayout>

在主方法中开启进度条,数据假设

private void initView() {
        progressBar = (CircleProgressBar) findViewById(R.id.progressBar);
        startBtn = (Button) findViewById(R.id.startBtn);
        stopBtn = (Button) findViewById(R.id.stopBtn);
        increaseBtn = (Button) findViewById(R.id.increaseBtn);
        increaseLittleBtn = (Button) findViewById(R.id.increaseLittleBtn);
        activity_main = (LinearLayout) findViewById(R.id.activity_main);

        startBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
        increaseBtn.setOnClickListener(this);
        increaseLittleBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.startBtn:
                progressBar.reStart();
                break;
            case R.id.stopBtn:
                progressBar.speedDown();
                break;
            case R.id.increaseBtn:
                progressBar.speedUp();
                break;
            case R.id.increaseLittleBtn:
                progressBar.setTextSize(progressBar.getTextSize()+2);
                break;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值