自定义控件2---圆形进度条

本文详细介绍了如何在Android中创建自定义圆形进度条View,包括定义属性、构造方法及重写onDraw方法等内容。

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

先来复习一下自定义View的步骤:

1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
[ 3、重写onMesure ]
4、重写onDraw

1、自定义View的属性, 在attrs.xml里面定义我们的属性和声明我们的整个样式。

    <declare-styleable name="RoundProgressBar">
<!--         圆环的颜色  -->
        <attr name="roundColor" format="color" />
<!--         圆环进度的颜色 -->
        <attr name="roundProgressColor" format="color" />
<!--         中间进度百分比的字符串的颜色 -->
        <attr name="progresstextColor" format="color" />
<!--         中间进度百分比的字符串的字体大小  -->
        <attr name="progresstextSize" format="dimension" />
<!--         圆环的宽度  -->
        <attr name="roundWidth" format="dimension" />
<!--         最大进度 -->
        <attr name="max" format="integer" />
<!--         当前进度 -->
        <attr name="progress" format="integer" />
<!--         是否显示中间的进度 字符串-->
        <attr name="textIsDisplayable" format="boolean" />
<!--         进度的风格,实心或者空心 -->
        <attr name="style">
            <enum name="STOKE" value="0" />
            <enum name="FILL" value="1" />
        </attr>
    </declare-styleable>

我们定义了9个属性,format是值该属性的取值类型:

然后在布局中声明我们的自定义View

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.pepe.widgetdemo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
<!-- 第一个取默认值 -->
    <com.pepe.widgetdemo.TwoRoundProgressBar
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <com.pepe.widgetdemo.TwoRoundProgressBar
        custom:style="STOKE"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="10dp"
        custom:max="200"
        custom:progress="100"
        custom:progresstextColor="#ff0000"
        custom:progresstextSize="20sp"
        custom:roundColor="#00ff00"
        custom:roundProgressColor="#0000ff"
        custom:roundWidth="15dp"
        custom:textIsDisplayable="true" />

</LinearLayout>

2、在View的构造方法中,获得我们的自定义的样式

public class TwoRoundProgressBar extends View {
    /**
     * 圆环的颜色
     */
    private int mRoundColor;
    /**
     * 圆环进度的颜色
     */
    private int mRoundProgressColor;
    /**
     * 中间进度百分比的字符串的颜色
     */
    private int mProgressTextColor;
    /**
     * 中间进度百分比的字符串的字体大小
     */
    private int mProgressTextSize;
    /**
     * 圆环的宽度
     */
    private int mRoundWidth;
    /**
     * 最大进度
     */
    private int mMax;
    /**
     * 当前进度
     */
    private int progress;
    /**
     * 是否显示中间的进度字符串
     */
    private boolean mTextIsDisplayable;
    /**
     * 进度的风格,实心或者空心
     */
    private int style;
    public static final int STROKE = 0;
    public static final int FILL = 1;
    /**
     * 画笔
     */
    private Paint mPaint;

    public TwoRoundProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);
        mRoundColor = typedArray.getColor(
                R.styleable.RoundProgressBar_roundColor, Color.YELLOW);
        mRoundProgressColor = typedArray.getColor(
                R.styleable.RoundProgressBar_roundProgressColor, Color.RED);
        mProgressTextColor = typedArray.getColor(
                R.styleable.RoundProgressBar_progresstextColor, Color.GREEN);
        mProgressTextSize = typedArray.getDimensionPixelSize(
                R.styleable.RoundProgressBar_progresstextSize, 15);
        mRoundWidth = typedArray.getDimensionPixelSize(
                R.styleable.RoundProgressBar_roundWidth, 5);
        progress = typedArray.getInteger(R.styleable.RoundProgressBar_progress, 33);
        mMax = typedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        mTextIsDisplayable = typedArray.getBoolean(
                R.styleable.RoundProgressBar_textIsDisplayable, false);
        style = typedArray.getInt(R.styleable.RoundProgressBar_style, 1);//默认实心
        typedArray.recycle();

        mPaint = new Paint();

    }
}

我们还是重写两个参数的构造方法,我们在构造方法中获得自定义属性。
3、我们重写onDraw,onMesure调用系统提供的:

@Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
    {  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
    }  
@Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        /**
         * 画最外层的大圆环
         */
        int centre = getWidth() / 2; // 获取圆心的x坐标
        int radius = (int) (centre - mRoundWidth / 2); // 圆环的半径
        mPaint.setColor(mRoundColor); // 设置圆环的颜色
        mPaint.setStyle(Paint.Style.STROKE); // 设置空心
        mPaint.setStrokeWidth(mRoundWidth); // 设置圆环的宽度
        mPaint.setAntiAlias(true); // 消除锯齿
        canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环

        /**
         * 画圆弧 ,画圆环的进度
         */
        mPaint.setStrokeWidth(mRoundWidth); // 设置圆环的宽度
        mPaint.setColor(mRoundProgressColor); // 设置进度的颜色
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限
                                            // ,用这个圆的外包矩形的左上角和右下角坐标来确定
        // 设置进度是实心还是空心
        switch (style) {
        case STROKE: {
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(oval, -90, 360 * progress / mMax, false, mPaint); // 根据进度画圆弧
            break;
        }
        case FILL: {
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            if (progress != 0)
                canvas.drawArc(oval, -90, 360 * progress / mMax, true, mPaint); // 根据进度画圆弧
            break;
        }
        }

        /** 
         * 画进度百分比 
         */  
        mPaint.setStrokeWidth(0);   
        mPaint.setColor(mProgressTextColor);  
        mPaint.setTextSize(mProgressTextSize);  
        mPaint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体  
        int percent = (int)(((float)progress / (float)mMax) * 100+0.5);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0  
        float textWidth = mPaint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间  

        if(mTextIsDisplayable  && style == STROKE){  
            canvas.drawText(percent + "%", centre - textWidth / 2, centre + mProgressTextSize/2, mPaint); //画出进度百分比  
        } 

    }

此时的效果是:
这里写图片描述

源码下载

引用:
Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条) - Mobile Internet developer - 博客频道 - youkuaiyun.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值