Android带进度的圆形进度条
我们还是用一个小例子来看看自定义view和自定义属性的使用,带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧
从上面可以看出,我们可以自定义圆环的颜色,圆环进度的颜色,是否显示进度的百分比,进度百分比的颜色,以及进度是实心还是空心等等,这样子是不是很多元化很方便呢?接下来我们就来教大家怎么来定义
1.在values下面新建一个attrs.xml,现在里面定义我们的属性,不同的属性对应不同的format,接下来我贴上我在自定义这个进度条所用到的属性
<?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> <attr name="textcolor" format="color" /> <attr name="textsize" format="dimension" /> <attr name="max" format="integer"></attr> <attr name="textisdisplayable" format="boolean"></attr> <attr name="style"> <enum name="stroke" value="0"></enum> <enum name="fill" value="1"></enum> </attr> </declare-styleable> </resources>
2.自定义view的属性我们算是定义好了,接下来就是怎么获取属性和代码的编写了,我们需要在构造方法中获取我们自己定义的相关属性,我们先调用context.obtainstyledattributes(attrs,r.styleable.roundprogressbar)来获取typedarray,然后从typedarray获取我们定义的属性,例如
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); max = mtypedarray.getinteger(r.styleable.roundprogressbar_max, 100); textisdisplayable = mtypedarray.getboolean(r.styleable.roundprogressbar_textisdisplayable, true); style = mtypedarray.getint(r.styleable.roundprogressbar_style, 0);
上面的代码中,如roundcolor = mtypedarray.getcolor(r.styleable.roundprogressbar_roundcolor, color.red); getcolor方法的第一个参数是我们在xml文件中定义的颜色,如果我们没有给我们自定义的view定义颜色,他就会使用第二个参数中的默认值,即color.red
3.为了方便大家理解,我将自定义view的全部代码贴出来,里面的代码我也有详细的注释
package com.example.roundprogressbar; import android.content.context; import android.content.res.typedarray; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.rectf; import android.graphics.typeface; import android.util.attributeset; import android.util.log; import android.view.view; import com.example.circlepregress.r; /** * 仿iphone带进度的进度条,线程安全的view,可直接在线程中更新进度 * @author xiaanming * */ public class roundprogressbar extends view { /** * 画笔对象的引用 */ private paint paint; /** * 圆环的颜色 */ private int roundcolor; /** * 圆环进度的颜色 */ private int roundprogresscolor; /** * 中间进度百分比的字符串的颜色 */ private int textcolor; /** * 中间进度百分比的字符串的字体 */ private float textsize; /** * 圆环的宽度 */ private float roundwidth; /** * 最大进度 */ private int max; /** * 当前进度 */ private int progress; /** * 是否显示中间的进度 */ private boolean textisdisplayable; /** * 进度的风格,实心或者空心 */ private int style; public static final int stroke = 0; public static final int fill = 1; public roundprogressbar(context context) { this(context, null); } public roundprogressbar(context context, attributeset attrs) { this(context, attrs, 0); } public roundprogressbar(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); paint = new paint(); 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); max = mtypedarray.getinteger(r.styleable.roundprogressbar_max, 100); textisdisplayable = mtypedarray.getboolean(r.styleable.roundprogressbar_textisdisplayable, true); style = mtypedarray.getint(r.styleable.roundprogressbar_style, 0); mtypedarray.recycle(); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); /** * 画最外层的大圆环 */ int centre = getwidth()/2; //获取圆心的x坐标 int radius = (int) (centre - roundwidth/2); //圆环的半径 paint.setcolor(roundcolor); //设置圆环的颜色 paint.setstyle(paint.style.stroke); //设置空心 paint.setstrokewidth(roundwidth); //设置圆环的宽度 paint.setantialias(true); //消除锯齿 canvas.drawcircle(centre, centre, radius, paint); //画出圆环 log.e("log", centre + ""); /** * 画进度百分比 */ paint.setstrokewidth(0); paint.setcolor(textcolor); paint.settextsize(textsize); paint.settypeface(typeface.default_bold); //设置字体 int percent = (int)(((float)progress / (float)max) * 100); //中间的进度百分比,先转换成float在进行除法运算,不然都为0 float textwidth = paint.measuretext(percent + "%"); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间 if(textisdisplayable && percent != 0 && style == stroke){ canvas.drawtext(percent + "%", centre - textwidth / 2, centre + textsize/2, paint); //画出进度百分比 } /** * 画圆弧 ,画圆环的进度 */ //设置进度是实心还是空心 paint.setstrokewidth(roundwidth); //设置圆环的宽度 paint.setcolor(roundprogresscolor); //设置进度的颜色 rectf oval = new rectf(centre - radius, centre - radius, centre + radius, centre + radius); //用于定义的圆弧的形状和大小的界限 switch (style) { case stroke:{ paint.setstyle(paint.style.stroke); canvas.drawarc(oval, 0, 360 * progress / max, false, paint); //根据进度画圆弧 break; } case fill:{ paint.setstyle(paint.style.fill_and_stroke); if(progress !=0) canvas.drawarc(oval, 0, 360 * progress / max, true, paint); //根据进度画圆弧 break; } } } public synchronized int getmax() { return max; } /** * 设置进度的最大值 * @param max */ public synchronized void setmax(int max) { if(max < 0){ throw new illegalargumentexception("max not less than 0"); } this.max = max; } /** * 获取进度.需要同步 * @return */ public synchronized int getprogress() { return progress; } /** * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 * 刷新界面调用postinvalidate()能在非ui线程刷新 * @param progress */ public synchronized void setprogress(int progress) { if(progress < 0){ throw new illegalargumentexception("progress not less than 0"); } if(progress > max){ progress = max; } if(progress <= max){ this.progress = progress; postinvalidate(); } } public int getcriclecolor() { return roundcolor; } public void setcriclecolor(int criclecolor) { this.roundcolor = criclecolor; } public int getcricleprogresscolor() { return roundprogresscolor; } public void setcricleprogresscolor(int cricleprogresscolor) { this.roundprogresscolor = cricleprogresscolor; } public int gettextcolor() { return textcolor; } public void settextcolor(int textcolor) { this.textcolor = textcolor; } public float gettextsize() { return textsize; } public void settextsize(float textsize) { this.textsize = textsize; } public float getroundwidth() { return roundwidth; } public void setroundwidth(float roundwidth) { this.roundwidth = roundwidth; } }
4.通过上面几步我们就实现了自定义view,和自定义view的属性,当然使用过程中还是有一点变化,我们必须在界面布局的最顶层加上
xmlns:android_custom=""这个即命名空间,
红色部分是自定义属性的前缀,什么意思呢?对于android系统控件我们定义其控件属性是用android:xxx="xxxxxxx",而我们自己定义的就用android_custom:xxx = "xxxxxx"
绿色部分则是我们的包的名字
通过上面这两步我们就能自己定义属性了,我贴出自定义view在xml中使用情况
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android_custom="http://schemas.android.com/apk/res/com.example.circlepregress" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.roundprogressbar.roundprogressbar android:id="@+id/roundprogressbar2" android:layout_width="80dip" android:layout_height="80dip" android:layout_alignleft="@+id/roundprogressbar1" android:layout_alignparentbottom="true" android:layout_marginbottom="78dp" android_custom:roundcolor="#d1d1d1" android_custom:roundprogresscolor="@android:color/black" android_custom:textcolor="#9a32cd" android_custom:textisdisplayable="false" android_custom:roundwidth="10dip" android_custom:textsize="18sp"/> </relativelayout>
源码下载: 《android带进度的圆形进度条》
以上就是本文的全部内容,希望对大家的学习有所帮助。