android之View和SurfaceView

本文对比了Android中View和SurfaceView的区别,详细介绍了如何自定义这两种视图,并提供了具体的实现代码示例。通过实例展示了如何在线程中更新UI,以及触摸和键盘事件的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先介绍一下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 } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.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(); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); myView=new MyView(this); setContentView(myView); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while(true){ try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } handler.sendEmptyMessage(REFRESH); //使用postInvalidate可以直接在线程中更新UI界面 //myView.postInvalidate(); } } }).start(); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub myView.r+=2; return super.onTouchEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(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); } @Override public void run() { // TODO Auto-generated method stub while(true){ //死循环 来不停地画 try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (surfaceHolder) { Draw(); } } } //绘图方法 public void Draw(){ //锁定画布 得到Canvas Canvas 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大小改变时激发 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } //在surface创建时激发 @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub //开启视图线程 new Thread(this).start(); } //在surface销毁时激发 @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } } SurfaceView不需要通过线程来更新视图,但在绘图之前必须使用lockCanvas方法锁定画布,并得到画布,然后在画布上绘制;当绘制完成后,使用unlockCanvasAndPost方法来解锁画布,这样才能显示在屏幕上。

public class TestSurfaceViewActivity extends Activity { MySurfaceView mySurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); mySurfaceView=new MySurfaceView(this); setContentView(mySurfaceView); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub mySurfaceView.r+=2; return super.onTouchEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(keyCode==KeyEvent.KEYCODE_BACK){ finish(); } return super.onKeyDown(keyCode, event); } }
运行效果和上面的一样,就不做演示了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值