结构:
BaseView:
package com.caiduping.canvas; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.View; 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); //线程挂起0.2秒 即画弧速度为0.2秒/弧度 } catch (InterruptedException e) { e.printStackTrace(); } } } } }
LogicView:
package com.caiduping.canvas; import java.util.Random; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; public class LogicView extends BaseView{ private Paint paint;//画笔 private int x=0; private RectF rectF=new RectF(150,150,380,380); /*Rect类主要用于表示坐标系中的一块矩形区域 * 并可以对其做一些简单操作。这块矩形区域 需要用左上右下两个坐标点表示(left,top,right,bottom) 如果你这么声明一个Rect类: Rect rect=new Rect(100,50,300,500); 那么右下角(300,500)其实是不在这个矩形里面的,但是左上角(100,50)在 也就是说,这个矩形实际表示的区域是:(100,50,299,499)*/ 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(30); } @Override protected final void onDrawSub(Canvas canvas) { canvas.drawText("Android之自定义画图文字动画", x, 100, paint); /*第一个参数是RectF左上的x y坐标 右下的x y坐标 第二个参数是 弧形的开始角度 第三个参数是 弧形的结束角度 第四个参数是 true:画扇形 false:画弧线 第五个参数是 画笔 */ canvas.drawArc(rectF, 0, sweepAngle, true, paint); } @Override protected void logic() { x+=20; sweepAngle+=5;//每次弧度加5 //随机设置画笔的颜色 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("Android之自定义画图文字动画");//测量文字宽度 x=0-textWidth; } } }
MainActivity:
setContentView(new LogicView(this));
run: