android之View和SurfaceView

来源:互联网 发布:linux递归设置权限 编辑:程序博客网 时间:2024/04/27 09:36

转载:

http://blog.csdn.net/wangkuifeng0118/article/details/7288968


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

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

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

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

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

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

       

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

      

[html] view plaincopy
  1. public class MyView extends View {  
  2.   
  3.     int count=0;       
  4.     public int r=10; //圆的半径  
  5.     public MyView(Context context) {  
  6.         super(context);  
  7.         // TODO Auto-generated constructor stub  
  8.     }  
  9.     @Override  
  10.     protected void onDraw(Canvas canvas) {  
  11.         // TODO Auto-generated method stub  
  12.         super.onDraw(canvas);  
  13.         if(count<=100){  
  14.             count++;      
  15.         }else{  
  16.             count=0;  
  17.         }  
  18.         //绘图  
  19.         Paint paint=new Paint();  
  20.         switch (count % 4) {  
  21.         case 0:  
  22.             paint.setColor(Color.BLUE);  
  23.             break;  
  24.         case 1:  
  25.             paint.setColor(Color.YELLOW);  
  26.             break;  
  27.         case 2:  
  28.             paint.setColor(Color.GRAY);  
  29.             break;  
  30.         case 3:  
  31.             paint.setColor(Color.RED);  
  32.             break;  
  33.         default:  
  34.             paint.setColor(Color.WHITE);  
  35.             break;  
  36.         }  
  37.         canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);  
  38.     }  
  39.   
  40. }  
      下面是需要显示它的TestViewActivity类:

invalidate   

[html] view plaincopy
  1. public class TestViewActivity extends Activity {  
  2.   
  3.     private MyView myView;  
  4.     private int REFRESH;  
  5.     private Handler handler=new Handler(){  
  6.         public void handleMessage(android.os.Message msg) {  
  7.             if(msg.what==REFRESH){  
  8.                 myView.invalidate();  
  9.             }  
  10.         };  
  11.     };  
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.         // TODO Auto-generated method stub  
  15.         super.onCreate(savedInstanceState);  
  16.         myView=new MyView(this);  
  17.         setContentView(myView);  
  18.           
  19.         new Thread(new Runnable() {  
  20.               
  21.             @Override  
  22.             public void run() {  
  23.                 // TODO Auto-generated method stub  
  24.                 while(true){  
  25.                 try {  
  26.                     Thread.sleep(200);  
  27.                 } catch (InterruptedException e) {  
  28.                     // TODO Auto-generated catch block  
  29.                     e.printStackTrace();  
  30.                 }  
  31.                 handler.sendEmptyMessage(REFRESH);  
  32.                 //使用postInvalidate可以直接在线程中更新UI界面  
  33.                 //myView.postInvalidate();  
  34.               }   
  35.             }  
  36.         }).start();  
  37.     }  
  38.     @Override  
  39.     public boolean onTouchEvent(MotionEvent event) {  
  40.         // TODO Auto-generated method stub  
  41.         myView.r+=2;  
  42.         return super.onTouchEvent(event);  
  43.           
  44.     }  
  45.     @Override  
  46.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  47.         // TODO Auto-generated method stub  
  48.         if(keyCode==KeyEvent.KEYCODE_BACK){  
  49.             finish();  
  50.         }  
  51.         return super.onKeyDown(keyCode, event);  
  52.     }  
  53. }  
    注释的部分是可以在线程中更新UI界面,当然也可以在handler中调用invalidate方法更新界面,这样就可以通过线程不断的重画改变小球的颜色,而且点击画面后小球会慢慢变大。

    这是其中的一张截图:

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

[html] view plaincopy
  1. public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {  
  2.   
  3.     SurfaceHolder surfaceHolder;  
  4.     int count=0;  
  5.     int r=10;  
  6.     public MySurfaceView(Context context) {  
  7.         super(context);  
  8.          //实例化SurfaceHolder对象  
  9.         surfaceHolder=this.getHolder();  
  10.         //为SurfaceHolder添加一个回调函数  
  11.         surfaceHolder.addCallback(this);  
  12.         this.setFocusable(true);  
  13.     }  
  14.   
  15.     @Override  
  16.     public void run() {  
  17.         // TODO Auto-generated method stub  
  18.         while(true){  //死循环 来不停地画  
  19.         try {  
  20.             Thread.sleep(200);  
  21.         } catch (InterruptedException e) {  
  22.             // TODO Auto-generated catch block  
  23.             e.printStackTrace();  
  24.         }  
  25.         synchronized (surfaceHolder) {  
  26.             Draw();  
  27.         }  
  28.        }  
  29.     }  
  30.     //绘图方法  
  31.     public void Draw(){  
  32.         //锁定画布  得到Canvas  
  33.         Canvas canvas=surfaceHolder.lockCanvas();  
  34.         if(surfaceHolder==null || canvas==null){  
  35.             return ;  
  36.         }  
  37.         if(count<=100){  
  38.             count++;  
  39.         }else{  
  40.             count=0;  
  41.         }  
  42.         Paint paint=new Paint();  
  43.         switch (count % 4) {  
  44.         case 0:  
  45.             paint.setColor(Color.BLUE);  
  46.             break;  
  47.         case 1:  
  48.             paint.setColor(Color.YELLOW);  
  49.             break;  
  50.         case 2:  
  51.             paint.setColor(Color.GRAY);  
  52.             break;  
  53.         case 3:  
  54.             paint.setColor(Color.RED);  
  55.             break;  
  56.         default:  
  57.             paint.setColor(Color.WHITE);  
  58.             break;  
  59.         }  
  60.         canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);  
  61.         //解锁画布  
  62.         surfaceHolder.unlockCanvasAndPost(canvas);  
  63.     }  
  64.     //在surface大小改变时激发  
  65.     @Override  
  66.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  67.             int height) {  
  68.         // TODO Auto-generated method stub  
  69.           
  70.     }  
  71.     //在surface创建时激发  
  72.     @Override  
  73.     public void surfaceCreated(SurfaceHolder holder) {  
  74.         // TODO Auto-generated method stub  
  75.         //开启视图线程  
  76.         new Thread(this).start();  
  77.     }  
  78.      //在surface销毁时激发  
  79.     @Override  
  80.     public void surfaceDestroyed(SurfaceHolder holder) {  
  81.         // TODO Auto-generated method stub  
  82.           
  83.     }  
  84.   
  85. }  
   SurfaceView不需要通过线程来更新视图,但在绘图之前必须使用lockCanvas方法锁定画布,并得到画布,然后在画布上绘制;当绘制完成后,使用unlockCanvasAndPost方法来解锁画布,这样才能显示在屏幕上。

  

[html] view plaincopy
  1. public class TestSurfaceViewActivity extends Activity {  
  2.     MySurfaceView  mySurfaceView;  
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         // TODO Auto-generated method stub  
  6.         super.onCreate(savedInstanceState);  
  7.          mySurfaceView=new MySurfaceView(this);  
  8.         setContentView(mySurfaceView);  
  9.     }  
  10.     @Override  
  11.     public boolean onTouchEvent(MotionEvent event) {  
  12.         // TODO Auto-generated method stub  
  13.         mySurfaceView.r+=2;  
  14.         return super.onTouchEvent(event);  
  15.     }  
  16.     @Override  
  17.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  18.         // TODO Auto-generated method stub  
  19.         if(keyCode==KeyEvent.KEYCODE_BACK){  
  20.             finish();  
  21.         }  
  22.         return super.onKeyDown(keyCode, event);  
  23.     }  
  24. }  

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