关于控件呢,我想大家应该都很熟悉了吧,android应用开发MVC架构中,控件担任着至关重要的作用,感觉可以说是基于控件的事件模型人机交互的基础吧。这种特性感觉在wpf开发中体现得更为直接,感兴趣的同学可以去了解一下。而android框架自身就已经给我们提供了很多控件。那么问题来了?为什么有那么多控件可以用,你还要去屑自定义控件呢?是因为大家闲的蛋疼吗?显然不是。个人认为只要有两方面吧,要么是觉得有些原生控件是在是丑得难以忍受(即使是在你已经自定义了他的shape,圆角,selector等一系列style以及annotation之后);还有最容易出现的原因就是原生控件已经难以满足你的需求。
好吧,我承认以上都是废话,可是我刚开始学java和android的时候,记得是大一暑假吧,当时我是真心不理解这些,当时要是有人更我说一下这些,我就不会那么迷茫了。
接下来就让我们来看一下,如何实现一个简单的圆形进度条吧。
首先你需要 extends View类。这样你就可以在需要的Activity或fragment里面引用你的自定义控件。而,圆形进度条的话,你就需要自己按照特定的规律来画圆(例如,倒计时,下载进度)。而extends View后,你需要重载protected void onDraw(Canvas canvas) 方法。之后,你便可以用canvas来会出你想要的形状。这里我们就画圆吧。
而画圆需要用到canvas.drawArc(oval, -90, ((float) progress / maxProgress) * 360, false, paint)方法。这里面第一个参数确定所画圆的范围。第二个参数确定开始画圆的位置,-90是从12点钟方向开始。第三个参数是每次绘制圆弧对应圆心角的度数。最后一个参数是设置画笔paint。
最关键的是第一个参数RectF,由他来确定在什么地方绘制圆弧,因为canvas所绘制的圆弧是由RectF所确定矩形区域的内切圆(尽管矩形并没有绘制出来,但是他真的存在,自行脑补)。RectF有四个参数,具体设置can jain下面的代码。接下来比价重要的就是paint了,你可以对paint设置颜色,线宽,是否抗锯齿等属性。
下面给出代码吧,里面有比较详细的注释。
package com.pocketdigi.curcleprogressbar.view;
import android.content.Context;
import android.graphics.Canvas;
android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class CircleProgressBar extends View {
private int maxProgress = 100;
private int progress = 30;
private int progressStrokeWidth = 4;
//画圆所在的距形区域
RectF oval;
Paint paint;
public CircleProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO 自动生成的构造函数存根
oval = new RectF();
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
// TODO 自动生成的方法存根
super.onDraw(canvas);
int width = this.getWidth();
int height = this.getHeight();
if(width!=height)
{
int min=Math.min(width, height);
width=min;
height=min;
}
paint.setAntiAlias(true); // 设置画笔为抗锯齿
paint.setColor(Color.WHITE); // 设置画笔颜色
canvas.drawColor(Color.TRANSPARENT); // 白色背景
paint.setStrokeWidth(progressStrokeWidth); //线宽
paint.setStyle(Style.STROKE);
oval.left = progressStrokeWidth / 2; // 左上角x
oval.top = progressStrokeWidth / 2; // 左上角y
oval.right = width - progressStrokeWidth / 2; // 左下角x
oval.bottom = height - progressStrokeWidth / 2; // 右下角y
canvas.drawArc(oval, -90, 360, false, paint); // 绘制白色圆圈,即进度条背景
paint.setColor(Color.rgb(0x57, 0x87, 0xb6));
canvas.drawArc(oval, -90, ((float) progress / maxProgress) * 360, false, paint); // 绘制进度圆弧,这里是蓝色
paint.setStrokeWidth(1);
String text = progress + "%";
int textHeight = height / 4;
paint.setTextSize(textHeight);
int textWidth = (int) paint.measureText(text, 0, text.length());
paint.setStyle(Style.FILL);
canvas.drawText(text, width / 2 - textWidth / 2, height / 2 +textHeight/2, paint);
}
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public void setProgress(int progress) {
this.progress = progress;
this.invalidate();
}
/**
* 非UI线程调用
*/
public void setProgressNotInUiThread(int progress) {
this.progress = progress;
this.postInvalidate();
}
}
下面就看一下如何来使用这个自定义控件吧。首先你需要在相应的XML文件中引用他。
<wenyue.justdoit.view.CircleProgressBar
android:id="@+id/circleProgressbar"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true" />
然后就是findViewById之类的,此处不再赘述。而当你拿到progressBar实例后,就可以给他设置一些参数,而这些set方法你必须在重写的类中实现它。例如:progressBar.setProgressNotInUiThread(i);
其他的,setOnclickListener之类的按需要设置即可。至此,一个简单的圆形进度条便已经大功告成了。哈哈。
原文地址:http://blog.csdn.net/canglangwenyue/article/details/41153819