上次已完成的自定義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.