fc2ブログ

レイアウトxmlでSurfaceViewを使用する

はじめに


久々の投稿です。以前、SurfaceViewについての記事を投稿しましたが、その際はSurfaceViewを画面全体に使用しており、レイアウトにxmlファイルを使用していませんでした。しかし、androidを開発する場合は、レイアウトはxmlファイルにまとめた方が何かと便利ですので、今回はxmlファイルを使用してSurfaceViewを画面上にレイアウトしてみたいと思います。


ポイント


今回のポイントは、SurfaceViewのためのコールバックをどうやって登録するか、です。そこさえ理解できれば、後は以前の記事と同じです。


プロジェクトの新規作成


いつものようにEclipseを起動して、新規プロジェクトを作成します。「ファイル」→「新規」→「Androidプロジェクト」を選択して、「新規Androidプロジェクト」ウィンドウを表示させます。そして以下を設定します。


プロジェクト名:SampleSurView


ビルド・ターゲット:Android 1.6


アプリケーション名:Sample Sur View


パッケージ名:jp.sample.SampleSurView


Create Activity:SampleSurView


リソースレイアウトの修正


以前、SurfaceViewを使用したサンプルでは、リソースレイアウトを使用していませんでした。しかし、今回はxmlファイルを使用してSurfaceViewをレイアウトします。


<?xml version="1.0" encoding="utf-8"?>

<TableLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TableLayoutMain">


<!-- メイン領域:SurfaceViewを使用する -->
<SurfaceView
android:id="@+id/SurfaceViewMain"
android:layout_width="fill_parent"
android:layout_height="100px">

</SurfaceView>

<!-- ボタン領域 -->
<TableRow
android:id="@+id/TableRowMenu"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<Button
android:id="@+id/ButtonA"
android:text="A">

</Button>
<Button
android:id="@+id/ButtonB"
android:text="B">

</Button>
<Button
android:id="@+id/ButtonC"
android:text="C">

</Button>
<Button
android:id="@+id/ButtonD"
android:text="D">

</Button>
</TableRow>
</TableLayout>

今回はシンプルなレイアウトです。画面上部にSurfaceViewを配置し、その下にボタンを4つ配置しています。これらのビューをうまく配置するために、TableLayoutも使用しています。実際にこれを実行すると、以下のような画面になります。


20100103_article1

レイアウトは以上になります。後はSurfaceViewに対してコールバックを登録すればOKです。


ソースコードの修正


今回はソースコードを2つに分けます。1つは普段生成するメインのアクティビティのソースコード、もう1つはSurfaceView用のソースコードです。まずは、SurfaceView用のソースコードから掲載します。


「MainSurfaceView.java」


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainSurfaceView implements SurfaceHolder.Callback, Runnable {
private SurfaceHolder holder;
private static final String LOG = "MainSurfaceView";

// コンストラクタ
public MainSurfaceView(Context context, SurfaceView sv) {
holder = sv.getHolder();
holder.addCallback(this);
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.d(LOG, "surfaceChanged");
}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.d(LOG, "surfaceCreated");

Canvas canvas = arg0.lockCanvas();
canvas.drawColor(Color.BLACK);

// canvasを使用してSurfaceViewに描画する
arg0.unlockCanvasAndPost(canvas);
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.d(LOG, "surfaceDestroyed");
}

@Override
public void run() {
Log.d(LOG, "run");
}
}

上記コードの一番のポイントは、コンストラクタの部分です。引数でSurfaceViewクラスのインスタンスをもらい、そこからgetHolderメソッドでSurfaceHolderを取得し、addCallbackメソッドで自クラスをコールバックとして登録します。これでOK。後は、上記MainSurfaceViewクラスをインスタンス化する時に、引数でSurfaceViewクラスのインスタンスを渡せば、SurfaceViewを使用することができます。


なお、MainSurfaceViewクラスの各メソッド(surfaceChanged, surfaceCreated, surfaceDestoryed, run)に、それぞれSurfaceViewを使用する際に実行したいコードを記述すれば、所望の動作をSurfaceViewに行わせることができます。今回はログを表示するのみ。




残りはメインのアクティビティのソースコードです。こちらのアクティビティから上記MainSurfaceViewクラスをインスタンス化します。


「SampleSurView.java」


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class SampleSurView extends Activity {
private SurfaceView mSvMain;
private MainSurfaceView mMainDrawArea;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// SurfaceViewを参照
mSvMain = (SurfaceView)findViewById(R.id.SurfaceViewMain);

// 作成したMainSurfaceViewクラスをインスタンス化
mMainDrawArea = new MainSurfaceView(this, mSvMain);
}
}

ポイントはonCreateメソッドの中の最後の二行です。まずはリソースレイアウトにて定義したSurfaceViewをfindViewByIdメソッドによって参照します。これはmSvMainというメンバに保持しておきます。次に、mSvMainをMainSurfaceViewクラスをインスタンス化する際の第二引数に渡します。すると、MainSurfaceViewクラスのコンストラクタ内で、第二引数で渡されたインスタンスを使用して、MainSurfaceViewクラスをSurfaceViewを使用するためのコールバックとして登録します(MainSurfaceView.javaファイル参照)。これだけです。


実行結果


今回は目に見える動作は何も実行していませんので、実行結果は特にありません。


おわりに


今回はSurfaceViewをリソースレイアウトxmlファイルで使用してみました。Androidアプリを開発する場合はxmlファイルでレイアウトをいじる場合が多いと思いますので、今回の例のようにSurfaceViewを使用する場合もリソースレイアウトでレイアウトする場合が多いと思います。



テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます
プロフィール

sepiablue

Author:sepiablue
組込みソフトウェアエンジニアやってます。普段はC言語使い。
趣味はプログラミング、京都旅行で神社巡り。
AndroidアプリをMacで開発中。

最新記事
スポンサードリンク
スポンサードリンク
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
QRコード
QRコード