2012年5月27日日曜日

SurfaceChanged method sample code

SurfaceChanged method sample code

SurfaceHolder.Callback interfaceには、surfaceChanged、surfaceCreated及びsurfaceDestroyedの3個のメソッドがある。
このうち、surfaceChangedメソッドが不明だったのでsample codeを作成してみた。

このsample codeのアプリを実行すると、1個のボタンと、その下にSurfaceViewが表示される。
ボタンを押し下げると、ボタンの大きさが変化する、このボタンの大きさに影響されてSurfaceViewの表示領域が変化し、surfaceChangedメソッドが呼ばれる。

SurfaceViewの表示領域が変化した時にsurfaceChangedメソッドが呼ばれるという、まさに当たり前の振る舞いではあるが、念のために確認した次第である。

取り敢えず、ゲームの作成には関係ないや、という安心感とともに、使いもしないメソッドを実装させられるムナシサを心に秘めつつ、訳の分からんドキュメントの解析にイソシムandroid programmerであった。

SurfaceHolder#setFixedSizeメソッドは、1回使うと、2回目以降は機能しない。
SurfaceHolder#setFormatメソッドを使うと、surfaceChangedメソッドは呼び出される。しかし、その呼出時に Canvas c = h.lockCanvas(); を行うと、「既にロックされている」という趣旨の実行時エラーが発生する。これは、詳しくは調べていない。

ちなみに、surfaceCreatedが呼ばれるのは、SurfaceViewの生成時である。
そして、それに加えて、startActivityメソッドを使って他のViewを呼び出し、そしてそのViewが消えて、再度、SurfaceViewが表示される時にもsurfaceCreatedが呼ばれる。この場合には SurfaceViewのコンストラクタは呼ばれない。
「戻る」キーを押し下げてSurfaceViewを消した場合には、次回のSurfaceViewの表示には、コンストラクタの実行が伴う。

public class SurfaceChangedActivity extends Activity
    implements
    OnClickListener
    {
    final String TAG = "me";
    MySurfaceView msv;
    Button bu;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bu = (Button)findViewById(R.id.Button);
        bu.setOnClickListener(this);
        msv = new MySurfaceView(this);
        LinearLayout llParent;
        llParent = (LinearLayout)findViewById(R.id.Main);
        llParent.addView(msv);
    }
    
    @Override
    public void onClick(View v) {
        if(v==bu){
            if(bu.getHeight()>100) bu.setHeight(80);
            else bu.setHeight(500);
            return;
        }
    }

    public class MySurfaceView extends SurfaceView implements Callback{
        public MySurfaceView(Context context) {
            super(context);
            getHolder().addCallback(this);
        }
        
        @Override
        public void surfaceCreated(SurfaceHolder h) {
            Canvas c = h.lockCanvas();
            LinearGradient(c);
            h.unlockCanvasAndPost(c);
        }

        @Override
        public void surfaceChanged(SurfaceHolder h,
                int format, int width, int height) {
            if(h.isCreating()==true) return;
            Log.d(TAG, "surfaceChanged : " + height);
            Canvas c = h.lockCanvas();
            LinearGradient(c);
            h.unlockCanvasAndPost(c);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
        
        private void LinearGradient(Canvas c){
            LinearGradient lg = new LinearGradient(
                    c.getWidth()/2, 0.0f, c.getWidth()/2, c.getHeight(),
                    Color.BLUE, Color.RED, Shader.TileMode.CLAMP);
            Paint p = new Paint();
            p.setShader(lg);
            c.drawPaint(p);
        }
    }
}

0 件のコメント:

コメントを投稿