一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧。
1.封装一个抽象的View类 BaseView.java
/**
* 封装基本View
* @author ansen
* @create time 2015-08-07
*/
public abstract class BaseView extends View{
private MyThread myThread;
public BaseView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BaseView(Context context) {
super(context);
}
protected abstract void onDrawSub(Canvas canvas);//绘制图像
protected abstract void logic();//逻辑方法 子类实现
@Override
protected void onDraw(Canvas canvas) {
if(null==myThread){
myThread=new MyThread();
myThread.start();
}else{
onDrawSub(canvas);
}
}
private boolean running=true;//控制循环
@Override
protected void onDetachedFromWindow() {
running=false;//销毁View的时候设置成false,退出无限循环
super.onDetachedFromWindow();
}
//开启一个子线程绘制ui
private class MyThread extends Thread{
@Override
public void run() {
while(running){
logic();
postInvalidate();//重新绘制,会调用onDraw
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2.在逻辑View类中实现自己想要绘制的内容 LogicView.java
1).集成BaseView,实现onDrawSub()跟logic()抽象方法
2).在onDraw()方法中绘制图形 例如:画弧形 画文字
3).onDrawSub()方法中实现绘制的逻辑
/**
* Android自定义View 画弧形,文字,并增加动画效果
* @author ansen
* @create time 2015-08-07
*/
public class LogicView extends BaseView{
private Paint paint;//画笔
private int x=0;
private RectF rectF=new RectF(150,150,380,380);
private int sweepAngle=0;//弧的结束度数
private Random random=new Random();
public LogicView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LogicView(Context context) {
super(context);
init();
}
//初始化画笔
private void init(){
paint=new Paint();
paint.setTextSize(60);
}
@Override
protected final void onDrawSub(Canvas canvas) {
canvas.drawText("Hello World", x, 100, paint);
//第一个参数是RectF 左上的x y坐标 右下的x y坐标
//第二个参数是 弧形的开始角度
//第三个参数是 弧形的结束角度
//第四个参数是 true:画扇形 false:画弧线
//第五个参数是 画笔
canvas.drawArc(rectF, 0, sweepAngle, true, paint);
}
@Override
protected void logic() {
x+=20;
sweepAngle+=3;//每次弧度加3
//随机设置画笔的颜色
int r=random.nextInt(255);
int g=random.nextInt(255);
int b=random.nextInt(255);
paint.setARGB(255, r, g, b);
if(sweepAngle>=360){//如果弧度大于360° 从头开始
sweepAngle=0;
}
if(x>getWidth()){//如果移动到屏幕外,从头开始
int textWidth=(int) paint.measureText("Hello World");//测量文字宽度
x=0-textWidth;
}
}
}
3.显示View的Activity MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new LogicView(this));
}
}
4.效果图如下: