surfaceView

  要自定义一个surfaceView首先就要继承 SurfaceView类并实现SurfaceHolder.Callback接口

  那么什么是接口回调呢?

  回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。   回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

  要实现下面的三个生命周期回调函数才能完整实现一个SurfaceView

  三个重要的生命周期回调函数:

 1.public abstract void surfaceCreated(SurfaceHolder holder)在SurfaceView创建时调用该函数。

 2.public abstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height),在SurfaceView改变时调用该函数。

 3.public abstract void surfaceDestroyed(SurfaceHolder holder)在SurfaceView销毁前调用该函数。

  SurfaceView中最重要的方法应该是protected void onDraw(Canvas canvas),它是用来绘制SurfaceView画面的,其中的参数canvas 是该SurfaceView的画笔。每一   次SurfaceView中画面的改变都是调用了该方法。

  通常方法是:新建一个线程类,每隔一个周期用一次SurfaceViewdeOnDraw()方法,而OnDraw()方法中的画面也有一个线程在时时改变,这样后一个线程类实      现了OnDraw()画面中显示内容的变化,前一个线程类时时刷新画面,这就形成了动画。

  不过在实现onDraw()函数却提示错误:Suspicious method call; should probably call "draw" rather than "onDraw",Google一下,改名为fix_onDraw()就可     以了,也许是有同名的函数。有待研究

  SurfaceHolder:

  public interface SurfaceHolder

  显示一个surface的抽象接口,使你可以控制surface的大小和格式, 以及在surface上编辑像素,和监视surace的改变。

  这个接口通常通过SurfaceView类实现

  surface的控制器,用来操纵surface,处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
  几个需要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
     // 给SurfaceView当前的持有者一个回调对象。
(2)、abstract Canvas lockCanvas();
    // 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
(3)、abstract Canvas lockCanvas(Rect dirty);
    // 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。
    // 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
    // 结束锁定画图,并提交改变。

 SurfaceHolder.Callback:
 用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时, 它只在SurfaceHolder.Callback.surfaceCreated()和  SurfaceHolder.Callback.surfaceDestroyed()之间有效。设置Callback的方法是SurfaceHolder.addCallback.

下面附上渐变的欢迎界面的SurfaceView实现的代码:

 1 package com.example.mytafanggame;
 2 
 3 import android.view.SurfaceView;
 4 import android.view.SurfaceHolder;
 5 import android.graphics.BitmapFactory;
 6 import android.graphics.Color;
 7 import android.graphics.Paint;
 8 import android.graphics.Bitmap;
 9 import android.graphics.Canvas;
10 
11 public class WelcomeView extends SurfaceView implements SurfaceHolder.Callback{
12     MyGameActivity activity;
13     Paint paint;
14     int   currentAlpha  = 0;                      //当前的不透明值
15     float screenWidth   = Constant.SCREEN_HEIGHT; //屏幕宽度
16     float screenHeight  = Constant.SCREEN_WIDTH;  //屏幕高度
17     int   sleepSpan     = 50;                     //动画延时
18     Bitmap[] logos = new Bitmap[2];               //logo图片
19     Bitmap currentLogo;                           //当前图片
20     int currentX;
21     int currentY;
22     
23     public WelcomeView(MyGameActivity activity){
24         super(activity);
25         this.activity = activity;
26         this.getHolder().addCallback(this);       //创建生命周期回调接口的实现
27         paint = new Paint();                      //创建画笔
28         paint.setAntiAlias(true);                 //打开抗锯齿
29         logos[0] = BitmapFactory.decodeResource(activity.getResources(), R.drawable.dukea);
30         logos[1] = BitmapFactory.decodeResource(activity.getResources(), R.drawable.welcome);
31     }
32     
33     public void fix_onDraw(Canvas canvas){
34         paint.setColor(Color.BLACK);
35         paint.setAlpha(255);                     //设置可见度
36         canvas.drawRect(0, 0,screenWidth,screenHeight,paint);
37         if(currentLogo == null)
38             return;
39         paint.setAlpha(currentAlpha);            //设置可见度
40         canvas.drawBitmap(currentLogo, currentX, currentY,paint);
41     }
42     
43     public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3){}
44     public void surfaceCreated(SurfaceHolder holder){
45         new Thread(){
46             public void run(){
47                 for(Bitmap bm:logos){
48                     currentLogo = bm;
49                     currentX = activity.screenWidth/2 - bm.getWidth()/2;   //绘制屏幕左边开始
50                     currentY = activity.screenHeight/2 - bm.getHeight()/2; //绘制屏幕上边开始
51                     for(int i=255; i>-10; i=i-10){                         //不同透明度重复绘制
52                         currentAlpha = i;
53                         if(currentAlpha < 0){                              //透明度为负数置为0
54                             currentAlpha = 0;
55                         }
56                     SurfaceHolder myholder = WelcomeView.this.getHolder();//获取surfaceHolder
57                     Canvas canvas = myholder.lockCanvas();                //锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了
58                     try {
59                         synchronized(myholder){                           //同步锁,一个时间内只有一个线程能执行下面代码块
60                             fix_onDraw(canvas);                           //绘制
61                         }
62                     }
63                     catch (Exception e){
64                         e.printStackTrace();
65                     }
66                     finally {
67                         if(canvas != null){
68                             myholder.unlockCanvasAndPost(canvas);        //结束锁定画图,并提交改变
69                         }
70                     }
71                     try {
72                         if(i == 255){
73                             Thread.sleep(1000);
74                         }
75                         Thread.sleep(sleepSpan);
76                     }
77                     catch (Exception e){
78                         e.printStackTrace();
79                     }
80                     }
81                 }
82                 activity.sendMessage(1);
83             }
84         }.start();
85     }
86     public void surfaceDestroyed(SurfaceHolder arg0){}
87 
88 }