项目需要,需要一个圆形的进度条,所想到的实现方案是这样的:
自定义View,订制一个圆形的进度条。下面简述实现,有不当之处敬请指正。
主题思想
- 自定义类继承自View,在构造函数中,获得从配置文件中获得的自定义属性值。
- 在onDraw中绘制,跟据获得的属性值,绘制想要的图形。
自定义属性的定义
在文件attrs.xml中
<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>
则,在layout文件中,可以使用这些自定义属性:
<com.running.aid.aidrunning.RoundProgressBar
android:id="@+id/roundProgressBar"
android:layout_width="250dip"
android:layout_height="250dip"
android:layout_alignParentTop="true"
android:layout_marginBottom="78dp"
android:layout_centerHorizontal="true"
android_custom:roundColor="#D1D1D1"
android_custom:roundProgressColor="@android:color/holo_green_light"
android_custom:textColor="@color/gray9"
android_custom:roundWidth="25dip"
android_custom:textSize="18sp" />
在自定义的进度条类的构造函数中,获取配置的自定义属性值:
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);
绘制控件
画最外层的大圆环
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); //画出圆环
绘制文本
这里是模仿计步器,显示的当前步数,总步数,分三行显示。
paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
//if(textIsDisplayable && percent != 0 && style == STROKE){
if(textIsDisplayable && style == STROKE){
stepNumValueStr = "" + currentValue;
stepAIMValueStr = "" + maxValue;
float stepNumStrWidth = paint.measureText(stepNumStr);
float stepAIMStrWidth = paint.measureText(stepAIMStr+stepAIMValueStr);
float y = paint.getFontMetrics().bottom - paint.getFontMetrics().top;
canvas.drawText(stepNumStr,centre-stepNumStrWidth/2,centre -2*y,paint);
canvas.drawText(stepAIMStr+stepAIMValueStr,centre-stepAIMStrWidth/2,centre+2*y,paint);
paint.setTextSize(textSize * 2);
paint.setColor(getResources().getColor(R.color.blue6));
float stepNumValueStrWidth = paint.measureText(stepNumValueStr);
canvas.drawText(stepNumValueStr,centre-stepNumValueStrWidth/2,centre,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;
}
}