アンドロイドのSurfaceViewを使ってみた

  SurfaceViewとは? ここではSurfaceViewのクラスを使って画像を画面に表示して…

 

SurfaceViewとは?

ここではSurfaceViewのクラスを使って画像を画面に表示してみます。SurfaceViewとはViewクラスを継承したクラスで、Viewクラスより高速に画面を生成することができるクラスで、主に三次元グラフィックスのように高速画面の切り替えによく使われるクラスです。以下は利用方法です。

  • SurfaceViewを継承し、SurfaceHolder.Callbackをimplementする
  • SurfaceHolderを生成する
  • SurfaceViewCallbackインタフェースをimplementするために以下のCallback methodをoverrideする
    ①SurfaceChanged() : SurfaceViewが変化するときのイベント処理を入れる(例えば、画面サイズ取得のような処理)
    ②SurfaceCreated() : SurfaceViewが生成されるときのイベント処理を入れる
    ③SurfaceDestroyed() : SurfaceViewがdestroyされるときのイベント処理を入れる(例えば、resource releaseのような処理)
  • lockCanvas(), unlockCanvasAndPost()のmethodを使って画面に出力する
  • ここではthreadのクラスを利用して独立的なthreadで画面を出力しています。このthreadを利用する場合はrunnableをimplementします。図1はSurfaceViewで作ってみたサンプル例の実行画面です。

    サンプルプログラム

    サンプルプログラム

    MainActivity.java

    package com.example.surfaceviewex;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.view.SurfaceView;
    import android.view.Window;
    
    public class MainActivity extends Activity {
    	private static final String LOG = "MainActivity";
    	
    	private MainSurfaceView 	mMainSurface;	
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		
    		requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_main);
    		
    		//get surfaceView on Layout
    		SurfaceView surface;
    		surface = (SurfaceView)findViewById(R.id.SurfaceViewMain);
    		mMainSurface = new MainSurfaceView(this, surface);
    	}
    }
    

    MainSurfaceView.java

    package com.example.surfaceviewex;
    
    import android.content.Context;
    import android.util.Log;
    import android.view.*;
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.PixelFormat;
    import android.view.SurfaceHolder.Callback;
    
    
    public class MainSurfaceView extends SurfaceView implements Callback, Runnable{
    	
    	private static final String LOG = "MainSurfaceView";
    	
        private SurfaceHolder 	mSurfaceHolder;
        private Thread 		  	thread;
        
        public  Bitmap			bitmapImage;
    
        public MainSurfaceView(Context context) {
            super(context);
            Log.d(LOG, "MainSurfaceView is constructed(Context)");
            this.mSurfaceHolder = this.getHolder();
            this.initSurfaceHolder();
        }
        
        public MainSurfaceView(Context context, SurfaceView sv) {
            super(context);       
        	Log.d(LOG, "MainSurfaceView is constructed(Context, SurfaceView)");
            this.mSurfaceHolder = sv.getHolder();
            this.initSurfaceHolder();
        }
    
        private void initSurfaceHolder(){
        	Log.d(LOG, "initSurfaceHolder method is fired");
        	this.mSurfaceHolder.addCallback(this);
        	Resources res = this.getContext().getResources();
        	bitmapImage = BitmapFactory.decodeResource(res, R.drawable.lena);
        	setFocusable(true);
        	requestFocus();
        }
        
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
        	Log.d(LOG, "surfaceChanged is fired");
        	this.mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
        }
        
        @Override
        public void surfaceCreated(SurfaceHolder holder){
        	thread = new Thread(this);		
        	thread.start(); 			// must be located in surfaceCreated()
        }
        public void surfaceDestroyed(SurfaceHolder holder){
        	thread = null;
        }
       
    	@Override
    	public void run() {
    		Log.d(LOG, "run is fired");
    		Canvas c = this.mSurfaceHolder.lockCanvas();
            c.drawBitmap(this.bitmapImage, 0, 0, null);
    		this.mSurfaceHolder.unlockCanvasAndPost(c);
    	}
    }
    

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:orientation = "vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        tools:context=".MainActivity" >
    
        <SurfaceView
    		android:id="@+id/SurfaceViewMain"
    	    android:layout_width="fill_parent"
    	    android:layout_height="420dp">
        </SurfaceView>
    
    </LinearLayout>