使用自定义控件绘制一个圆环,需要重现的方法是OnDraw()实现对view的绘制,从而输出符合自己需求的view控件
观察圆环的组成部分: 外层圆+中间百分比文字+不断变化进度的弧形圈 --->分析:每一个组成部分需要的属性,构成几个关键的自定义属性
1:外层圆的颜色 2:弧形进度圈的颜色 3:中间百分比文字的颜色 4:中间百分比文字的大小 5:圆环的宽度(作为进度弧形圈的宽度)
6:*首页当中也有一个圆环进度,为了兼容使用首页的圆环进度,增加一个自定义属性,绘制进度弧形圈的风格(实心[Fill],空心[Stroken]) 分析完毕-->绘制步骤: 1:构造方法当中初始化画笔对象,获取自定义的属性值. 2:重写Ondraw方法 ---2.1:绘制最外层的圆 -关键方法canvas.drawCircle(center,
center, radius, paint); //画出圆环 *:计算半径、中心点坐标、画笔设置 中心点坐标 int center = getWidth() / 2; //获取圆心的x坐标 半径: int
radius = (int) (center - roundWidth/2) ---画图说明最容易理解 ---2.2:绘制中间的百分比文字 --关键方法:canvas.drawText(percent + "%", center - textWidth / 2, center + textSize / 2, paint); //画出进度百分比
测量画笔上的文本宽度 float textWidth = paint.measureText(percent + "%");
画笔设置 绘制的文字的位置,由参数2,3的X,Y坐标值决定--圆环的中心点位置显示 X:表示从哪开始绘制,如果你直接中心点开始绘制-->画图说明最容易理解 -->正确的X=center - textWidth / 2;Y = center
+ textSize / 2 --(因为android坐标系与数学坐标系Y轴值是相反的,也可以画图说明,这里的textsize就可以代表高度,paint.measureText测量方法执行之后,默认的文字高度就是根据文字大小计算的,相当于wrap_content,所以textSize就是本身文字所占的高度值) *:绘制的进度要转换为百分比形式:int percent = (int) (((float) progress /
(float) max) * 100); ---2.3:绘制进度弧形圈 ---关键方法:canvas.drawArc(oval, 0, 360 * progress / max, false, paint); //根据进度画圆弧 参数解释: oval:绘制的弧形的范围轮廓
0:从多少角度开始绘制 360 * progress / max:绘制弧形扫过的角度对应的区域 false:不包含圆心,如果是true,表示包含圆心 paint:绘制使用的画笔 画笔设置
paint.setStrokeWidth(roundWidth); //设置进度弧形圈的宽度,必须保持和外层圆的StrokeWidth一致,确保弧形圈绘制的时候覆盖的范围就是外层圆的宽度 paint.setColor(roundProgressColor); //设置进度的颜色
弧形范围计算 RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); --->画图说明最容易理解
*:注意,因为progress是相对于100当中占比多少,而弧形总共是按照角度分成360分的,所以绘制弧形圈指定参数扫过的区域角度需要计算转换一下 =360 * progress / max(max=100) 最后提供一个设置进度,根据进度重新绘制圆环的方法
.....圆环绘制自定义控件分析end...........................................................................|


RoundProgress
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | public class RoundProgress 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 RoundProgress(Context context) { this (context, null ); } public RoundProgress(Context context, AttributeSet attrs) { this (context, attrs, 0 ); } public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr) { super (context, attrs, defStyleAttr); TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress); //圆环的颜色 roundColor = mTypedArray.getColor(R.styleable.RoundProgress_roundColor, Color.RED); //圆环进度的颜色 roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgress_roundProgressColor, Color.GREEN); //中间进度百分比文字字符串的颜色 textColor = mTypedArray.getColor(R.styleable.RoundProgress_textColor, Color.GREEN); //中间进度百分比的字符串的字体大小 textSize = mTypedArray.getDimension(R.styleable.RoundProgress_textSize, 15 ); //圆环的宽度 roundWidth = mTypedArray.getDimension(R.styleable.RoundProgress_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 ; 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 ); 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(); } } |
?
1 2 3 4 5 6 7 8 9 10 | <?xml version= "1.0" encoding= "utf-8" ?> <resources> <declare-styleable name= "RoundProgress" > <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" /> </declare-styleable> </resources> |
?
1 2 3 4 5 6 7 8 9 10 11 | <!-- 圆环进度--> <cn.wh.ui.RoundProgress android:id= "@+id/p_progresss" android:layout_width= "120dp" android:layout_height= "120dp" app:roundColor= "@android:color/darker_gray" app:roundProgressColor= "@android:color/holo_red_dark" app:roundWidth= "10dp" app:textColor= "#18b4ed" app:textSize= "20sp" > </cn.wh.ui.RoundProgress> |
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private Runnable runnable = new Runnable() { @Override public void run() { int tempProgress = 0 ; try { while (tempProgress <= totalProgress) { pProgresss.setProgress(tempProgress); tempProgress++; Thread.sleep( 100 ); } } catch (InterruptedException e) { e.printStackTrace(); } } }; |