前一篇文章为自定义组件实现了描画功能,但是代码中的描画动作都是硬编码,无法由开发者控制。本文对之前的代码进行重构,以对外提供控制接口。
定义RoundProgressBar内部类
定义一个实现单个进度条功能的内部类,用于管理每个进度条的边缘颜色,内部颜色,最大值,最小值和当前值。
class RoundProgressBar{
MultiRoundProgressBar ownerBar;
private Color edgeColor;
private Color barColor;
private float minValue;
private float maxValue;
private float progressValue;
RoundProgressBar(MultiRoundProgressBar owner, Color edge, Color bar, float min, float max){
ownerBar = owner;
edgeColor = edge;
barColor = bar;
minValue = min;
maxValue = max;
progressValue = 0;
}
void setValue(float value){
progressValue = value;
}
void onDraw(Canvas canvas, Paint paint, RectFloat rect, float width, boolean active){
float startAngle = ownerBar.minAngle - 90;
float sweepAngle = (progressValue - minValue)/(maxValue - minValue) * (ownerBar.maxAngle - ownerBar.minAngle);
if(active){
width *= 0.8f;
}
else{
width *= 0.6f;
}
paint.setColor(edgeColor);
paint.setStrokeWidth(width);
canvas.drawArc(rect, new Arc(startAngle, sweepAngle, false), paint);
paint.setColor(barColor);
paint.setStrokeWidth(width * 0.8f);
canvas.drawArc(rect, new Arc(startAngle, sweepAngle, false), paint);
}
}
重构MultiRoundProgressBar
增加List成员,以管理RoundProgressBar对象;增加active_bar对象,以管理当前激活的进度条。
List<RoundProgressBar> barList;
private int active_bar = 0;
增加addBar和setValue方法,用于增加进度条和设定进度值。
public void addBar(Color edge, Color bar, float min, float max){
barList.add(new RoundProgressBar(this, edge, bar, min, max));
}
public void setValue(int index, float value){
barList.get(index).setValue(value);
}
重构描画相关方法:
@Override
public void onDraw(Component component, Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.WHITE);
canvas.drawRect(getBoundRect(), paint);
paint.setStyle(Paint.Style.STROKE_STYLE);
paint.setStrokeCap(Paint.StrokeCap.SQUARE_CAP);
for(int i = 0; i < barList.size(); i++){
barList.get(i).onDraw(canvas, paint, getProgressRect(i), barWidth(), i==active_bar);
}
}
private RectFloat getBoundRect(){
int width = getWidth();
int height = getHeight();
int size = Math.min(width, height);
int x_padding = (width - size) / 2;
int y_padding = (height - size) / 2;
return new RectFloat(x_padding, y_padding, width - x_padding, height - y_padding);
}
private float barWidth()
{
RectFloat bound = getBoundRect();
if(barList.size() > 0) {
return bound.getWidth() / 2 * 0.7f / barList.size();
}
else{
return 0;
}
}
private RectFloat getProgressRect(int round_index)
{
RectFloat arcRect = getBoundRect();
arcRect.shrink(barWidth(), barWidth());
arcRect.shrink(barWidth() * round_index, barWidth() * round_index);
return arcRect;
}
使用自定义接口
下面的代码增加增加4个进度条并指定当前值。增加进度条是可以指定边界颜色,进度条颜色,最大值和最小值。
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
MultiRoundProgressBar bar = (MultiRoundProgressBar) findComponentById(ResourceTable.Id_mrprogressId);
bar.addBar(Color.BLACK, Color.LTGRAY, 0, 100);
bar.setValue(0, 50);
bar.addBar(Color.BLUE, Color.WHITE, 0, 100);
bar.setValue(1, 60);
bar.addBar(Color.BLACK, Color.CYAN, 0, 100);
bar.setValue(2, 70);
bar.addBar(Color.BLACK, Color.RED, 0, 100);
bar.setValue(3, 80);
}
}
效果展示
下面的代码执行之后的效果:
最外层的灰色进度条处于活动状态。
参考代码
完整代码可以从以下链接下载:
https://github.com/xueweiguo/Harmony/tree/master/CustomizeComponent
作者著作介绍
《实战Python设计模式》是作者去年3月份出版的技术书籍,该书利用Python 的标准GUI 工具包tkinter,通过可执行的示例对23 个设计模式逐个进行说明。这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。
对设计模式感兴趣而且希望随学随用的读者通过本书可以快速跨越从理解到运用的门槛;希望学习Python GUI 编程的读者可以将本书中的示例作为设计和开发的参考;使用Python 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。