今天又花了一些时间看了鸿洋老师的博客,继续学习了 关于自定义view的相关,这次是实现类似圆形进度条的CircleProgressBarView;
还是自定义View的四个步骤(温习一下):
1. 在 res/values/ 下写 attrs.xml 文档来定义自定义View的样式;
2. 在自定义view的构造函数中获取自定义样式属性;
3. 重写 onDraw函数;
4. 重写 onMeasure函数;
OK,先 po一张 要实现的View的样子:
对,大概就是这个样子,然后两种颜色切换360度画圆。。
OK,首先 attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="customFirstColor" format="color"/>
<attr name="customSecondColor" format="color"/>
<attr name="customCircleWidth" format="dimension"/>
<attr name="customSpeed" format="integer"/>
<declare-styleable name="CustomCircleProgressBarView">
<attr name="customFirstColor"/>
<attr name="customSecondColor"/>
<attr name="customCircleWidth"/>
<attr name="customSpeed"/>
</declare-styleable>
</resources>
为了实现这样的效果,我们自定义了四个属性:第一圈颜色,第二圈颜色, 圈的宽度以及 画圆的速度。。。感觉自定义view,好的角色拆分很重要啊。。
OK, 然后 第二步:
<pre name="code" class="java"> private int mFirstColor;
private int mSecondColor;
private int mCircleWidth;
private int mSpeed;
private int mProgress;
private boolean isNext;
private Paint mPaint;
public CustomCircleProgressBarView(Context context){
this(context , null);
}
public CustomCircleProgressBarView(Context context , AttributeSet attrs){
this(context , attrs , 0);
}
public CustomCircleProgressBarView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs , defStyle);
TypedArray array = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CustomCircleProgressBarView , defStyle , 0);
int n = array.getIndexCount();
for(int i = 0; i< n;i ++){
int attr = array.getIndex(i);
switch (attr){
case R.styleable.CustomCircleProgressBarView_customFirstColor:
mFirstColor = array.getColor(attr , Color.BLUE);
break;
case R.styleable.CustomCircleProgressBarView_customSecondColor:
mSecondColor = array.getColor(attr , Color.BLUE);
break;
case R.styleable.CustomCircleProgressBarView_customCircleWidth:
mCircleWidth = array.getDimensionPixelSize(attr ,
(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP
,20, getResources().getDisplayMetrics()));
break;
case R.styleable.CustomCircleProgressBarView_customSpeed:
mSpeed = array.getInt(attr , 20);
break;
}
}
array.recycle();
mPaint = new Paint();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
mProgress++;
if(mProgress == 360){
mProgress = 0;
isNext = ! isNext;
}
postInvalidate();
try {
Thread.sleep(mSpeed);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
}
在构造函数里获取 自定义样式 属性,然后 开线程 用于 绘制策略。。。 注意 postInvalidate() 和 invalidate()在更新 UI 时的区别。。这里在新线程中做更新,只能用postInvalidate()。。。
然后 重写 onDraw():
@Override
protected void onDraw(Canvas canvas) {
int centre = getWidth() / 2;
int radius = centre - mCircleWidth / 2;
mPaint.setStrokeWidth(mCircleWidth);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
RectF oval = new RectF(centre - radius , centre - radius, centre + radius, centre + radius);
if(!isNext){
mPaint.setColor(mFirstColor);
canvas.drawCircle(centre, centre, radius, mPaint);
mPaint.setColor(mSecondColor);
canvas.drawArc(oval , -90 , mProgress , false, mPaint);
}else{
mPaint.setColor(mSecondColor);
canvas.drawCircle(centre , centre , radius , mPaint);
mPaint.setColor(mFirstColor);
canvas.drawArc(oval , -90 , mProgress , false, mPaint);
}
}
OK, 最后在 所需要用到改 自定义View的布局文件中 定义就好:
<com.example.dxdrush.customcircleprogressbarviewdemo.views.CustomCircleProgressBarView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
custom:customFirstColor="#22ff22"
custom:customSecondColor="#ff22ff"
custom:customCircleWidth="20dp"
custom:customSpeed="20"
/>