Android SurfaceView学习笔记
com.thinkive.ziyouxing.views; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import com.thinkive.adf.log.Logger; /** * 文件名: com.thinkive.ziyouxing.views.GameView * 作者: 熊杰 * 日期: 14-4-14 * 时间: 13:40 * 开发工具: IntelliJ IDEA 12.0.4 * 开发语言: Java,Android * 开发框架: * 版本: v0.1 * <strong>说明</strong> * <p></p> */ public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable { private SurfaceHolder surfaceHolder; private Canvas canvas; private Paint paint; //默认情况下是一直在运行的 private boolean isRunning = true; //半径增加 private int x = 0; public GameView(Context context) { super(context); surfaceHolder = this.getHolder(); surfaceHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { new Thread(this).start(); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) { } /** * 当SurfaceView消毁时执行,当应用程序退出时,当前SurfaceView就消毁掉了,子线程在运行过程中还在往界面上进行绘制, * View都没有了,怎么能往上面进行绘制呢?所以在运行过程中会出异常。 * <p/> * 当View消毁的时候就记线程不要再进行绘制了。 * * @param surfaceHolder */ @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { isRunning = false; } @Override public void run() { while (isRunning) { try { drawView(); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 用线程画图 * <p/> * 在做游戏开发的时候,我们要定期的对屏幕进行刷新.即在线程里面每隔100毫秒,屏幕会绘制一遍。线程什么时候启动呢? * <p/> * SurfaceView创建成功之后,有界面了,创建一个启动线程线程一启动,每过100毫秒就绘制一遍界面。 * <p/> * 只画边界,而不填充里面的颜色,该如何做呢? * <p/> * paint.setStyle(Paint.Style.STROKE); * 界面被消毁的时候,首先是Canvas被消毁,然后SurfaceHolder才会被消毁 */ private void drawView() { try { if (null != surfaceHolder) { canvas = surfaceHolder.lockCanvas(); paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(3); canvas.drawCircle(200, 200, x++, paint); } } catch (Exception e) { Logger.info(this.getClass(), "画图异常", e); } finally { if (null != canvas) { surfaceHolder.unlockCanvasAndPost(canvas); } } } /** * 让子线程提前结束,当按键的时候,首先按件事件被响应,这个响应完了之后,界面才退出。也就是从事件开始执行,到界面消毁中间还有那么一段时间,如果在此方法中就让线程终止运行 * 当界面真正消毁的时候,子线程已经结束了。 * @param keyCode * @param event * @return */ // @Override // public boolean onKeyDown(int keyCode, KeyEvent event) { // if(keyCode == KeyEvent.KEYCODE_BACK){ // isRunning = false; // } // return true; // } }
package com.thinkive.ziyouxing.views; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * 文件名: com.thinkive.ziyouxing.views.GameView * 作者: 熊杰 * 日期: 14-4-14 * 时间: 13:40 * 开发工具: IntelliJ IDEA 12.0.4 * 开发语言: Java,Android * 开发框架: * 版本: v0.1 * <strong>说明</strong> * <p></p> */ public class GameView1 extends SurfaceView{ //可以理解为指向SurfaceView的一个指针,可以类比成控制电视机的摇控器,而SurfaceView则是电视机,以后如果要控制电视机, //则只需操作摇控器就可以了。 private SurfaceHolder surfaceHolder; //面板对象 private Canvas canvas; //画笔 private Paint paint; /** * 当我对象创建成功之后,构造器就会获得执行,但是构造器执行的时候,界面并没有显示出来。对象是有了,但是界面并没有真正的画上去,我们应该等当前屏幕画上去了, * 我再通过屏幕锁定,我获得一个面板,面板再画才可以,因为现在对象刚刚创建成功,界面还没有出来,获取到的面板是空的,所以也就不能进行绘制了,那么现在我怎么确定执行画图的时候, * 这个View界面已经创建成功了呢? * SurfaceView里面有一个辅助类,sh.addCallBack()这个回调类似于注册监听,比如说按钮的单击监听,还有触摸监听,按键监听等等。 * 也就是说在SurfaceHolder上面注册一个监听,当SurfaceHolder状态改变的时候,监听里面的方法会自动执行。 * 说SurfaceHolder状态改变,实际上也就是SurfaceView的一个状态的改变, * 我们再写事件监听的时候,基本上所有的事件监听,所涉及到的那些方法,都是回调方法。 * * 什么是回调方法呢? * * 也就是这些方法不是我去调用的,而是系统去调用的。 * @param context */ public GameView1(Context context) { super(context); surfaceHolder = this.getHolder(); surfaceHolder.addCallback(new GameViewCallBack()); } class GameViewCallBack implements SurfaceHolder.Callback{ //当SurfaceView创建成功了执行 @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { //锁定面板之后,会得到一个Canvas,将面板锁定之后,我就可以进行绘画了,比如画圆,画直线... Canvas canvas = surfaceHolder.lockCanvas(); paint = new Paint(); paint.setColor(Color.RED); canvas.drawLine(0,0,100,100,paint); //绘制结束之后,解除面板锁定,并且发送,把当前已经画好的面板,发送到屏幕界面上。把面板发送,发送到哪儿呢?发送到界面上进行显示。我们说它自带二级缓存,这个地方就体现了二级缓存, //是我先锁定,不操作先锁定,整个画完之后,显示就可以了。 surfaceHolder.unlockCanvasAndPost(canvas); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height ) { } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。