Android 自定义View -带进度的圆形进度条

本文介绍了如何在Android中创建自定义View并设置属性。通过定义attrs.xml文件来声明自定义属性,并在布局文件中引用这些属性。文章还详细展示了如何在自定义View的构造方法中读取这些属性值,并通过重写onDraw方法实现特定的绘制效果。

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

转:http://blog.youkuaiyun.com/xiaanming/article/details/10298163

http://blog.youkuaiyun.com/lmj623565791/article/details/24252901/

1、自定义View的属性

2、在View的构造方法中获得我们自定义的属性

[ 3、重写onMesure ]

4、重写onDraw

我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。

1、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundProgressBar">
        <attr name="roundColor" format="color" />
        <attr name="roundProgressColor" format="color" />
        <attr name="roundWidth" format="dimension" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

我们定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:

一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;。

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app_custom="http://schemas.android.com/apk/res-auto"
    tools:context="example.com.roundprogress.MainActivity">

    <example.com.roundprogress.ui.RoundProgressBar
        android:layout_centerInParent="true"
        android:id="@+id/p_progress"
        android:layout_width="120dp"
        android:layout_height="120dp"
        app_custom:roundColor="@android:color/darker_gray"
        app_custom:roundProgressColor="@android:color/holo_red_dark"
        app_custom:roundWidth="5dp"
        app_custom:textColor="#18b4ed"
        app_custom:textSize="20sp"
        >
    </example.com.roundprogress.ui.RoundProgressBar>
</RelativeLayout>

Eclipse中对于自定义属性的引用是在根布局文件中声明一个命名空间引入 xmlns:app_custom="http://schemas.android.com/apk/res/xxxxx"我们的命名空间,后面的xxxxxx包路径指的是项目的package

而在Android Studio中声明命名控件和在Eclipse中类似,例如:xmlns:app_custom=”http://schemas.android.com/apk/res-auto”,

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

public class RoundProgressBar extends View {

    private Paint paint = new Paint();
    private int roundColor;
    private int roundProgressColor;
    private int textColor;
    private float textSize;
    private float roundWidth;

    private int max = 100;
    private int progress = 50;

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

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

    public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性值
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);
        //圆环颜色
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
        //圆环进度条颜色
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
        //中间文字进度的字体的颜色
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
        //中间文字进度的字体的大小
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
        //圆环的宽度
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);

        mTypedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //第一步:绘制一个最外层的圆
        paint.setColor(roundColor); //设置圆环的颜色
        paint.setStrokeWidth(roundWidth);//设置圆环的宽度 
        paint.setStyle(Paint.Style.STROKE);//设置空心 
        paint.setAntiAlias(true);//消除锯齿
        int center = getWidth() / 2;//获取圆心的x坐标
        int radius = (int) (center - roundWidth / 2);//圆环的半径
        canvas.drawCircle(center, center, radius, paint);//画出圆环

        //第二步:绘制正中间的文本
        float textWidth = paint.measureText(progress + "%");
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setStrokeWidth(0);
        paint.setTypeface(Typeface.MONOSPACE); //设置字体 
        canvas.drawText(progress + "%", center - textWidth / 2, center + textSize / 2, paint);

        //第三步
        //第三步:
        /**
         * 参数解释:
         * oval:绘制弧形圈所包含的矩形范围轮廓
         * 0:开始的角度
         * 360 * progress / max:扫描过的角度
         * false:是否包含圆心
         * paint:绘制弧形时候的画笔
         */
        RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);
        paint.setColor(roundProgressColor);
        paint.setStrokeWidth(roundWidth);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawArc(oval, 0, 360 * progress / max, false, paint);

    }

    public void setProgress(int progress) {
        this.progress = progress;
        if (progress > 100) {
            this.progress = 100;
        }
        postInvalidate();
    }
}

我们重写了3个构造方法,默认的布局文件调用的是两个参数的构造方法,所以记得让所有的构造调用我们的三个参数的构造,我们在三个参数的构造中获得自定义属性。

3、我们重写onDraw,onMesure调用系统提供的:

@Override
    protected void onDraw(Canvas canvas) {
        //第一步:绘制一个最外层的圆
        paint.setColor(roundColor); //设置圆环的颜色
        paint.setStrokeWidth(roundWidth);//设置圆环的宽度 
        paint.setStyle(Paint.Style.STROKE);//设置空心 
        paint.setAntiAlias(true);//消除锯齿
        int center = getWidth() / 2;//获取圆心的x坐标
        int radius = (int) (center - roundWidth / 2);//圆环的半径
        canvas.drawCircle(center, center, radius, paint);//画出圆环

        //第二步:绘制正中间的文本
        float textWidth = paint.measureText(progress + "%");
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setStrokeWidth(0);
        paint.setTypeface(Typeface.MONOSPACE); //设置字体 
        canvas.drawText(progress + "%", center - textWidth / 2, center + textSize / 2, paint);

        //第三步
        //第三步:
        /**
         * 参数解释:
         * oval:绘制弧形圈所包含的矩形范围轮廓
         * 0:开始的角度
         * 360 * progress / max:扫描过的角度
         * false:是否包含圆心
         * paint:绘制弧形时候的画笔
         */
        RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);
        paint.setColor(roundProgressColor);
        paint.setStrokeWidth(roundWidth);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawArc(oval, 0, 360 * progress / max, false, paint);

    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值