上次已完成的自定義View
public class LogicView extends View {
private Paint paint = new Paint();
private int rx = 0;
private MyThread myThread = null;
private String showString = "show me";
private RectF rectF = new RectF(0, 40, 600, 640);
private float sweepAngle = 0;
public LogicView(Context context) {
super(context);
}
public LogicView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setTextSize(200);
canvas.drawText(showString, rx, 300, paint);
canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true?
if (myThread == null) {
myThread = new MyThread();
myThread.start();
}
//invalidate(); //cal by ui thread
//postInvalidate();
//canvas.drawText("hi",rx,300,paint);
}
class MyThread extends Thread {
@Override
public void run() {
Random random = new Random();
super.run();
while (true) {
if (rx > getWidth()) {
rx = 0 - (int) paint.measureText(showString);
}
if (sweepAngle > 360) {
sweepAngle = 0;
}
paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important
rx = rx + 20;
sweepAngle += 2;
postInvalidate();//call by non-UI thread
try {
Thread.sleep(30);//important !!!
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
但要修改和重用會好難,所以要提取和封裝
0.change the name to BaseView
1. 在onDraw中,把
取出,put in to the new Method logic
drawsub
void drawsub(Canvas canvas){
paint.setTextSize(200);
canvas.drawText(showString, rx, 300, paint);
canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true?
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawsub(canvas);
if (myThread == null) {
myThread = new MyThread();
myThread.start();
}
//invalidate(); //cal by ui thread
//postInvalidate();
//canvas.drawText("hi",rx,300,paint);
}
2.in the MyThread run() method
pull out
if (rx > getWidth()) {
rx = 0 - (int) paint.measureText(showString);
}
if (sweepAngle > 360) {
sweepAngle = 0;
}
paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important
rx = rx + 20;
sweepAngle += 2;
put into logic method
void logic(){
if (rx > getWidth()) {
rx = 0 - (int) paint.measureText(showString);
}
if (sweepAngle > 360) {
sweepAngle = 0;
}
paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important
rx = rx + 20;
sweepAngle += 2;
}
public void run() {
super.run();
while (running) {
logic();
postInvalidate();//call by non-UI thread
System.out.println("thread still running");
try {
Thread.sleep(30);//important !!!
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3. add protected abstract inforant of the logic and drawsub method
protected abstract void drawsub(Canvas canvas);
protected abstract void logic();
4.Finally .BaseView
package pom.poly.com.trymakeviewbymyself.myView.v3;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by User on 14/10/2015.
*/
public abstract class BasicView extends View {
private MyThread myThread = null;
private boolean running = true;
public BasicView(Context context) {
super(context);
}
public BasicView(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected abstract void drawsub(Canvas canvas);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (myThread == null) {
myThread = new MyThread();
myThread.start();
} else {
drawsub(canvas);
}
//invalidate(); //cal by ui thread
//postInvalidate();
//canvas.drawText("hi",rx,300,paint);
}
protected abstract void logic();
@Override
protected void onDetachedFromWindow() {
running=false;
super.onDetachedFromWindow();
System.out.println("in onDetachedFromWindow");
}
class MyThread extends Thread {
@Override
public void run() {
super.run();
while (running) {
logic();
postInvalidate();//call by non-UI thread
System.out.println("thread still running");
try {
Thread.sleep(30);//important !!!
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
5. craet LogicView, extends Basae View, overide the logic and drawsub
package pom.poly.com.trymakeviewbymyself.myView.v3;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import java.util.Random;
/**
* Created by User on 14/10/2015.
*/
public class LogicView extends BasicView {
private Paint paint = new Paint();
private int rx = 0;
private Random random = new Random();
private String showString = "show me";
private RectF rectF = new RectF(0, 40, 600, 640);
private float sweepAngle = 0;
public LogicView(Context context) {
super(context);
}
public LogicView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void drawsub(Canvas canvas) {
paint.setTextSize(200);
canvas.drawText(showString, rx, 300, paint);
canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true?
}
@Override
protected void logic() {
if (rx > getWidth()) {
rx = 0 - (int) paint.measureText(showString);
}
if (sweepAngle > 360) {
sweepAngle = 0;
}
paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important
rx = rx + 20;
sweepAngle += 2;
}
}
Now,the view is more easy to change .
The finall important thing is , How to prevent the thread that we create keep run after exit then app?
protected void onDetachedFromWindow() {
running=false;
super.onDetachedFromWindow();
System.out.println("in onDetachedFromWindow");
}
onDetachedFromWindow call when view detach from the window
at this method,when we seat the boolean to false, the thread stop to loop.