surfaceview详解

简介: 1.概念       SurfaceView是View类的子类,可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图视图。它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。 2.实现方法 1)实现步骤

1.概念

      SurfaceView是View类的子类,可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图视图。它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。

2.实现方法

1)实现步骤

    a.继承SurfaceView

    b.实现SurfaceHolder.Callback接口

2)需要重写的方法

  1. public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}  //在surface的大小发生改变时激发  
  1. public void surfaceCreated(SurfaceHolder holder){}  //在创建时激发,一般在这里调用画图的线程。  
  1. public void surfaceDestroyed(SurfaceHolder holder) {}  //销毁时激发,一般在这里将画图的线程停止、释放。  

 

3)SurfaceHolder

  SurfaceHolder,surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
几个需要注意的方法:

  1. abstract void addCallback(SurfaceHolder.Callback callback);  
  2. // 给SurfaceView当前的持有者一个回调对象。  
  3. abstract Canvas lockCanvas();  
  4. // 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。  
  5. abstract Canvas lockCanvas(Rect dirty);  
  6. // 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。  
  7. // 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。  
  8. abstract void unlockCanvasAndPost(Canvas canvas);  
  9. // 结束锁定画图,并提交改变。  

4)总结整个过程

  继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

下面是一个完整的案例:

  1. public class ViewTest extends Activity {    @Override  
  2.       public void onCreate(Bundle savedInstanceState) {  
  3.          super.onCreate(savedInstanceState);  
  4.          setContentView(new MyView(this));  
  5.       }     //视图内部类  
  6.       class MyView extends SurfaceView implements SurfaceHolder.Callback  
  7.       {  
  8.          private SurfaceHolder holder;  
  9.          private MyThread myThread;   
  10.          public MyView(Context context) {  
  11.              super(context);  
  12.              // TODO Auto-generated constructor stub  
  13.              holder = this.getHolder();  
  14.              holder.addCallback(this);  
  15.              myThread = new MyThread(holder);//创建一个绘图线程  
  16.          }  
  17.     
  18.          @Override  
  19.          public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  20.                   int height) {  
  21.              // TODO Auto-generated method stub  
  22.                  
  23.          }  
  24.     
  25.          @Override  
  26.          public void surfaceCreated(SurfaceHolder holder) {  
  27.               // TODO Auto-generated method stub  
  28.              myThread.isRun = true;  
  29.              myThread.start();  
  30.         }  
  31.     
  32.         @Override  
  33.          public void surfaceDestroyed(SurfaceHolder holder) {  
  34.             // TODO Auto-generated method stub  
  35.             myThread.isRun = false;  
  36.         }  
  37.       }  
  38.       //线程内部类  
  39.       class MyThread extends Thread  
  40.       {  
  41.           private SurfaceHolder holder;  
  42.           public boolean isRun ;  
  43.           public  MyThread(SurfaceHolder holder)  
  44.           {  
  45.               this.holder =holder;   
  46.               isRun = true;  
  47.           }  
  48.           @Override  
  49.           public void run()  
  50.           {  
  51.               int count = 0;  
  52.               while(isRun)  
  53.               {  
  54.                   Canvas c = null;  
  55.                   try  
  56.                   {  
  57.                       synchronized (holder){  
  58.                         c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。  
  59.                     c.drawColor(Color.BLACK);//设置画布背景颜色  
  60.                     Paint p = new Paint(); //创建画笔  
  61.                     p.setColor(Color.WHITE);  
  62.                     Rect r = new Rect(10050300250);  
  63.                     c.drawRect(r, p);  
  64.                     c.drawText("这是第"+(count++)+"秒"100310, p);  
  65.                     Thread.sleep(1000);//睡眠时间为1秒  
  66.                   }  
  67.               }  
  68.               catch (Exception e) {  
  69.                   e.printStackTrace();  
  70.               }  
  71.               finally  
  72.               {  
  73.                    if(c!= null)  
  74.                  {  
  75.                    holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。  
  76.                 }  
  77.            }  
  78.          }  
  79.        }  
  80.      }  
  81.   } 
目录
相关文章
|
8月前
|
Android开发
Android 使用MediaPlayer和SurfaceView播放视频
Android 使用MediaPlayer和SurfaceView播放视频
67 0
|
10月前
|
API 异构计算
SurfaceView 和 TextureView
SurfaceView 和 TextureView
271 0
|
11月前
|
前端开发 Android开发
SurfaceView的那点事儿
SurfaceView的那点事儿
89 0
RecyclerView 添加动画
RecyclerView 添加动画
167 0
|
XML Android开发 数据格式
Fragment生命周期的坑和DialogFragment宽高的坑
最近在开发单页面应用,多个fragment嵌套在一个activity里面,和之前单个Fragment依赖在activivty中管理还是有点不同,我这Fragment嵌套了3层,最终还是出问题了。
2376 0