首先介绍一下View类,View类是android的一个超类,每一个View都有一个用于绘画的画布,这个画布可以进行任意的扩展。有的时候我们需要自定义VIew实现自己想要的视图。view、SurfaceView是游戏开发中经常用到的视图。

View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢。

SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快。

下面介绍一下View和SurfaceView区别:

View:必须在UI的主线程中更新画面,用于被动更新画面。

  surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。


先实现一个VIew的例子,新建一个MyView类基础View:

public class MyView extends View {int count=0;     public int r=10; //圆的半径public MyView(Context context) {super(context);// TODO Auto-generated constructor stub}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);if(count<=100){count++;}else{count=0;}//绘图Paint paint=new Paint();switch (count % 4) {case 0:paint.setColor(Color.BLUE);break;case 1:paint.setColor(Color.YELLOW);break;case 2:paint.setColor(Color.GRAY);break;case 3:paint.setColor(Color.RED);break;default:paint.setColor(Color.WHITE);break;}canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);}}
下面是需要显示它的TestViewActivity类:

invalidate

public class TestViewActivity extends Activity {private MyView myView;private int REFRESH;private Handler handler=new Handler(){public void handleMessage(android.os.Message msg) {if(msg.what==REFRESH){myView.invalidate();}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);myView=new MyView(this);setContentView(myView);new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}handler.sendEmptyMessage(REFRESH);//使用postInvalidate可以直接在线程中更新UI界面//myView.postInvalidate();  }}}).start();}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubmyView.r+=2;return super.onTouchEvent(event);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// TODO Auto-generated method stubif(keyCode==KeyEvent.KEYCODE_BACK){finish();}return super.onKeyDown(keyCode, event);}}
注释的部分是可以在线程中更新UI界面,当然也可以在handler中调用invalidate方法更新界面,这样就可以通过线程不断的重画改变小球的颜色,而且点击画面后小球会慢慢变大。

这是其中的一张截图:

下面看一下用SurfaceView是怎么实现的,照例创建一个MySurfaceView类:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {SurfaceHolder surfaceHolder;int count=0;int r=10;public MySurfaceView(Context context) {super(context); //实例化SurfaceHolder对象surfaceHolder=this.getHolder();//为SurfaceHolder添加一个回调函数surfaceHolder.addCallback(this);this.setFocusable(true);}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){  //死循环 来不停地画try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}synchronized (surfaceHolder) {Draw();}   }}//绘图方法public void Draw(){//锁定画布  得到CanvasCanvas canvas=surfaceHolder.lockCanvas();if(surfaceHolder==null || canvas==null){return ;}if(count<=100){count++;}else{count=0;}Paint paint=new Paint();switch (count % 4) {case 0:paint.setColor(Color.BLUE);break;case 1:paint.setColor(Color.YELLOW);break;case 2:paint.setColor(Color.GRAY);break;case 3:paint.setColor(Color.RED);break;default:paint.setColor(Color.WHITE);break;}canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);//解锁画布surfaceHolder.unlockCanvasAndPost(canvas);}    //在surface大小改变时激发@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}    //在surface创建时激发@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stub//开启视图线程    new Thread(this).start();} //在surface销毁时激发@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub}}
SurfaceView不需要通过线程来更新视图,但在绘图之前必须使用lockCanvas方法锁定画布,并得到画布,然后在画布上绘制;当绘制完成后,使用unlockCanvasAndPost方法来解锁画布,这样才能显示在屏幕上。

public class TestSurfaceViewActivity extends Activity {MySurfaceView  mySurfaceView;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState); mySurfaceView=new MySurfaceView(this);setContentView(mySurfaceView);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubmySurfaceView.r+=2;return super.onTouchEvent(event);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// TODO Auto-generated method stubif(keyCode==KeyEvent.KEYCODE_BACK){finish();}return super.onKeyDown(keyCode, event);}}

运行效果和上面的一样,就不做演示了。




更多相关文章

  1. Android的线程和线程池————读书笔记
  2. 【Handler详解和例子】
  3. Android:子线程向UI主线程发送消息
  4. 【Android】消息机制应用
  5. 专题 - Web应用->Web应用中适配不同屏幕
  6. Android线程模型(Painless Threading) --- 转
  7. Android四大组件:Service史上最全面解析
  8. Android学习感悟之消息机制
  9. 为什么说invalidate()不能直接在线程中调用

随机推荐

  1. Android Push
  2. Android配置build.gradle自动化编译signi
  3. Android 下的 bolts tasks
  4. Android桌面二:Android桌面widget
  5. Android(安卓)Studio 使用Gradle引入第三
  6. 【Android实战决】Android沉浸式状态栏实
  7. Android,百度,云知声tts总结
  8. Pure Android
  9. UI 初步介绍
  10. Android 技术专题系列之十七 -- volume 服