アプリ開発・Linuxサーバ環境構築からSEOまで初心者向けのプログラミング技術を紹介しています。

カスタムViewの実装の仕方

2011年9月26日(月) 3:43 PM

カスタムビューを使って、画面の真ん中に円を描くサンプルをつくってみました。

ボタンやテキストビューなど初めから用意されているViewだけでなく、自分自身でカスタムしたオリジナルViewを実装することができます。カスタムビューはゲームや複雑なアプリをつくるときに使われます。

Sample Image

◆実装の仕方◆
①Viewを継承したCustomViewクラスのための新しいファイル「CustomView.java」を作成する。

「CustomView.java」のソースコード

package com.appliinfo.android.samplethree;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CustomView extends View
{
	private Context mContext;
	private Paint mCirclePaint = new Paint();

	//コンストラクタ
	public CustomView(Context context) {
		super(context);
		mContext = context;
	}

	public CustomView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
	}

	@Override
	protected void onDraw(Canvas canvas)
	{
		super.onDraw(canvas);

		canvas.drawColor(Color.WHITE);

		//画面のサイズを取得
		int width = getWidth();
		int height = getHeight();

		//ペイントの色とスタイルをセット(色:青色 スタイル:図形の中を塗りつぶす)
		mCirclePaint.setARGB(255, 153, 204, 255);
		mCirclePaint.setStyle(Paint.Style.FILL);

		//画面の中心に円を描く
		canvas.drawCircle(width / 2, height / 2, 25, mCirclePaint);

	}

}

②res/layout/main.xmlにカスタムViewをセットする。

res/layout/main.xmlのソースコード

<?xml version=”1.0″ encoding=”utf-8″?>
<com.appliinfo.android.samplethree.CustomView xmlns:android=”http://schemas.android.com/apk/res/android
android:id=”@+id/customview”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:background=”#FF000000″>
</com.appliinfo.android.samplethree.CustomView>

LayoutInflaterを使ってmain.xmlからViewを生成し、setContentView()でセットする。

LayoutInflaterを使うと、動的にレイアウトxmlからViewを生成することができるので、プログラム実行中にレイアウトを切り替えることもできるそうです。

「SampleThree.java」のソースコード

package com.appliinfo.android.samplethree;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class SampleThree extends Activity {

    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LayoutInflater factory = LayoutInflater.from(this);

        // Set game layout
        View view = factory.inflate(R.layout.main, null);
        setContentView(view);

    }
}

残りの設定(AndroidManifest.xml)は、新しいプロジェクトをつくった時のままです。

MediaPlayerを使ったサウンドの再生

2011年6月19日(日) 4:08 PM

◆MediaPlayerの特徴:データをストリーム形式で読み込み、破棄する。BGMなどの大きいファイルを再生するときによく使われる。

良い点:メモリの負担が小さい
悪い点:呼び出しから再生までの時間がSoundPoolに比べて遅い

◆MediaPlayerを使って、サウンドを再生するには、以下のようにします。
*サウンド再生
private MediaPlayer mBgm;
this.mBgm = MediaPlayer.create(this, R.raw.bgm_title);
this.mBgm.setLooping(true);
this.mBgm.setVolume(1.0f, 1.0f);
mBgm.seekTo(0);
mBgm.start();

*サウンドの休止
mBgm.pause();

*サウンドの停止と破棄
mBgm.stop();
mBgm.release();

◆MediaPlayerクラスのメソッド
○MediaPlayer.create(Context context, int resid)
第一引数:コンテキスト 第二引数:リソースID

○setLooping(boolean looping)
第一引数:ループするかどうか(true:ループする false:ループしない)

○setVolume(float leftVolume, float rightVolume)
ボリューム設定(0.0~1.0の間で設定する)

○seekTo(int msec)
音楽の開始位置をミリ秒単位で指定する。

◆ブログ記事「SoundPoolを利用したサウンドの再生」のサンプルに、MediaPlayerを利用したサウンドの再生機能を加えてみました。

*変更点
①「res」→「raw」フォルダの中にbgm_title.midファイルを加えました。
②src/com.example.android.sample/Sample.javaの変更

package com.example.android.sampletwo;

import android.app.Activity;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

public class SampleTwo extends Activity {
 private TextView aTextView;
 private TextView bTextView;
 private char[] charactor = new char[4];
 private String moji;
 private int x, y;
 private SoundPool mSoundPool;
 private int SoundId;
 private MediaPlayer mBgm;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);

        aTextView = (TextView) findViewById(R.id.myTextView);
     bTextView = (TextView) findViewById(R.id.myTextPosition);

        //データの書き込み
     SharedPreferences pref = this.getSharedPreferences("MemoPrefs", MODE_PRIVATE);
     aTextView.setText(pref.getString("memo", ""));
     bTextView.setText("X:" + pref.getInt("xposition", 0) + " Y:" + pref.getInt("yposition", 0));

     //SoundPoolの生成と読み込み
     this.mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
     this.SoundId = mSoundPool.load(this, R.raw.sb_blast, 1);

     //MediaPlayerの生成と読み込み
     this.mBgm = MediaPlayer.create(this, R.raw.bgm_title);
     this.mBgm.setLooping(true);
     this.mBgm.setVolume(1.0f, 1.0f);

         mBgm.seekTo(0);
         mBgm.start();

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

     x = (int)event.getX();
     y = (int)event.getY();

     switch (event.getAction()) {

      case MotionEvent.ACTION_DOWN:
       charactor[0] = (char)(68); //D
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(87); //W
       charactor[3] = (char)(78); //N
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_UP:
       charactor[0] = (char)(85); //U
       charactor[1] = (char)(80); //P
       charactor[2] = (char)(32); //スペース
       charactor[3] = (char)(32); //スペース
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       mSoundPool.play(SoundId, 1.0f, 1.0f, 1, 0, 1.0f);
       break;

      case MotionEvent.ACTION_MOVE:
       charactor[0] = (char)(77); //M
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(86); //V
       charactor[3] = (char)(69); //E
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_CANCEL:
       aTextView.setText("ACTION_CANCEL");
       break;

       }

     return super.onTouchEvent(event);
     }

    protected void onResume() {
     super.onResume();

         mBgm.start();
    }

    protected void onRestart() {
     super.onRestart();

         mBgm.start();
    }

    protected void onPause() {
     super.onPause();

         mBgm.pause();
    }

    protected void onStop() {
     super.onStop();

     //データの保存
     SharedPreferences pref = this.getSharedPreferences("MemoPrefs", MODE_PRIVATE);
     SharedPreferences.Editor editor = pref.edit();
     editor.putString("memo", aTextView.getText().toString());
     editor.putInt("xposition", x);
     editor.putInt("yposition", y);
     editor.commit();

     mBgm.pause();
    }

    protected void onDestroy() {
     super.onDestroy();

         mBgm.stop();
         mBgm.release();
    }

}

SoundPoolを利用したサウンドの再生

2011年6月17日(金) 3:05 PM

◆SoundPoolの特徴:データをメモリに保存してから、再生を行うため、サウンドエフェクト(SE)の再生に向いています。

良い点:呼び出しから再生までの時間が短い。
悪い点:メモリの負担が大きい。

◆SoundPoolを使って、サウンドを再生するには、以下のようにします。
private SoundPool mSoundPool;
private int SoundId;
this.mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
this.SoundId = mSoundPool.load(this, R.raw.sb_blast, 1);
mSoundPool.play(SoundId, 1.0f, 1.0f, 1, 0, 1.0f);

◆SoundPoolクラスのメソッド
○SoundPool(int maxStreams, int streamType, int srcQuality)
第一引数:読み込むファイルの数

○load(Context context, int resId, int priority)
第一引数:コンテキスト 第二引数:リソースID

○play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
第五引数:ループ回数(0:ループしない -1:無限ループ)

◆ブログ記事「SharedPreferencesを使ったデータの保存と書き込み」のサンプルに、SoundPoolを利用したサウンドの再生機能を加えてみました。

*変更点
①「res」フォルダに「raw」フォルダ作成し、sb_blast.oggファイルを加えました。
②src/com.example.android.sample/Sample.javaの変更

package com.example.android.sampletwo;

import android.app.Activity;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

public class SampleTwo extends Activity {
 private TextView aTextView;
 private TextView bTextView;
 private char[] charactor = new char[4];
 private String moji;
 private int x, y;
 private SoundPool mSoundPool;
 private int SoundId;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);

        aTextView = (TextView) findViewById(R.id.myTextView);
     bTextView = (TextView) findViewById(R.id.myTextPosition);

        //データの書き込み
     SharedPreferences pref = this.getSharedPreferences("MemoPrefs", MODE_PRIVATE);
     aTextView.setText(pref.getString("memo", ""));
     bTextView.setText("X:" + pref.getInt("xposition", 0) + " Y:" + pref.getInt("yposition", 0));

     //SoundPoolの生成と読み込み
     this.mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
     this.SoundId = mSoundPool.load(this, R.raw.sb_blast, 1);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

     x = (int)event.getX();
     y = (int)event.getY();

     switch (event.getAction()) {

      case MotionEvent.ACTION_DOWN:
       charactor[0] = (char)(68); //D
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(87); //W
       charactor[3] = (char)(78); //N
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_UP:
       charactor[0] = (char)(85); //U
       charactor[1] = (char)(80); //P
       charactor[2] = (char)(32); //スペース
       charactor[3] = (char)(32); //スペース
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       mSoundPool.play(SoundId, 1.0f, 1.0f, 1, 0, 1.0f);
       break;

      case MotionEvent.ACTION_MOVE:
       charactor[0] = (char)(77); //M
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(86); //V
       charactor[3] = (char)(69); //E
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_CANCEL:
       aTextView.setText("ACTION_CANCEL");
       break;

       }

     return super.onTouchEvent(event);
     }

    protected void onStop() {
     super.onStop();

     //データの保存
     SharedPreferences pref = this.getSharedPreferences("MemoPrefs", MODE_PRIVATE);
     SharedPreferences.Editor editor = pref.edit();
     editor.putString("memo", aTextView.getText().toString());
     editor.putInt("xposition", x);
     editor.putInt("yposition", y);
     editor.commit();
    }

}

SharedPreferencesを使ったデータの保存と書き込み

2011年6月15日(水) 2:22 PM

SharedPreferencesを使うと、データの保存と書き込みが簡単にできます。

データの書き込み
aTextView = (TextView) findViewById(R.id.myTextView);
SharedPreferences pref = this.getSharedPreferences(“MemoPrefs”, MODE_PRIVATE);
aTextView.setText(pref.getString(“memo”, “”));

説明:
“MemoPrefs”という名前のxmlファイルを呼び出して、その中にある、”memo”という名前が付けられたデータをaTextViewにセットしています。また、データの書き込みはonCreateメソッドの中で処理を行うのが一般的みたいです。

データの保存
aTextView = (TextView) findViewById(R.id.myTextView);
int x = 10;
SharedPreferences pref = this.getSharedPreferences(“MemoPrefs”, MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(“memo”, aTextView.getText().toString());
editor.putInt(“xposition”, x);
editor.commit();

説明:
“MemoPrefs”という名前のxmlファイルを呼び出して、pref.edit();でxmlファイルを編集できるようにします。次に、”memo”という名前のデータにテキストビューの文字列を代入し、”xposition”のデータにxの値を代入しています。最後に、editor.commit();して、実行しています。また、データの書き込みはonStopメソッドの中で処理を行うのが一般的みたいです。

◆SharedPreferencesで保存したデータは、
アプリを実行した状態で、「Eclipse」の「DDMS」→「ファイル・エクスプローラー」タブを選択する。

フォルダ「data」→「data」→「パッケージ名」→「shared_prefs」→「MemoPrefs.xml」に保存されています。

中身を見る場合は、MemoPrefs.xmlを選択し、「ファイル・エクスプローラー」タブの横にあるアイコン(マウスを乗せるとPull a file from the deviceと表示される)をクリックし、任意の場所にエクスポートします。◆

ブログ記事「タッチパネルの位置情報を調べる」のサンプルに、SharedPreferencesを使ったデータの保存と書き込み機能を加えてみました。

*src/com.example.android.sample/Sample.javaの変更後の全ソース:

package com.example.android.sampletwo;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

public class SampleTwo extends Activity {
 private TextView aTextView;
 private TextView bTextView;
 private char[] charactor = new char[4];
 private String moji;
 private int x, y;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);

        aTextView = (TextView) findViewById(R.id.myTextView);
     bTextView = (TextView) findViewById(R.id.myTextPosition);

        //データの書き込み
     SharedPreferences pref = this.getSharedPreferences("MemoPrefs", MODE_PRIVATE);
     aTextView.setText(pref.getString("memo", ""));
     bTextView.setText("X:" + pref.getInt("xposition", 0) + " Y:" + pref.getInt("yposition", 0));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

     x = (int)event.getX();
     y = (int)event.getY();

     switch (event.getAction()) {

      case MotionEvent.ACTION_DOWN:
       charactor[0] = (char)(68); //D
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(87); //W
       charactor[3] = (char)(78); //N
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_UP:
       charactor[0] = (char)(85); //U
       charactor[1] = (char)(80); //P
       charactor[2] = (char)(32); //スペース
       charactor[3] = (char)(32); //スペース
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_MOVE:
       charactor[0] = (char)(77); //M
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(86); //V
       charactor[3] = (char)(69); //E
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_CANCEL:
       aTextView.setText("ACTION_CANCEL");
       break;

       }

     return super.onTouchEvent(event);
     }

    protected void onStop() {
     super.onStop();

     //データの保存
     SharedPreferences pref = this.getSharedPreferences("MemoPrefs", MODE_PRIVATE);
     SharedPreferences.Editor editor = pref.edit();
     editor.putString("memo", aTextView.getText().toString());
     editor.putInt("xposition", x);
     editor.putInt("yposition", y);
     editor.commit();
    }

}

タッチパネルの位置情報を調べる

2011年6月14日(火) 4:02 PM

タッチパネルの位置情報を調べるには、onTouchEventメソッド内で、

event.getX()
event.getY()

を使います。パネルのタッチしているX座標とY座標がわかります。

ブログ記事「char配列を、String変数に変換する」のサンプルに、タッチパネルの位置情報を表示する機能を加えてみました。

タッチパネル位置情報1

画面をタッチすると

タッチパネル位置情報2

*src/com.example.android.sample/Sample.javaの変更後の全ソース:

package com.example.android.sampletwo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

public class SampleTwo extends Activity {
 private TextView aTextView;
 private TextView bTextView;
 private char[] charactor = new char[4];
 private String moji;
 private int x, y;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

     aTextView = (TextView) findViewById(R.id.myTextView);
     bTextView = (TextView) findViewById(R.id.myTextPosition);
     x = (int)event.getX();
     y = (int)event.getY();

     switch (event.getAction()) {

      case MotionEvent.ACTION_DOWN:
       charactor[0] = (char)(68); //D
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(87); //W
       charactor[3] = (char)(78); //N
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_UP:
       charactor[0] = (char)(85); //U
       charactor[1] = (char)(80); //P
       charactor[2] = (char)(32); //スペース
       charactor[3] = (char)(32); //スペース
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_MOVE:
       charactor[0] = (char)(77); //M
       charactor[1] = (char)(79); //O
       charactor[2] = (char)(86); //V
       charactor[3] = (char)(69); //E
       moji = String.valueOf(charactor);
       aTextView.setText(moji);
       bTextView.setText("X:" + x + " Y:" + y);
       break;

      case MotionEvent.ACTION_CANCEL:
       aTextView.setText("ACTION_CANCEL");
       break;

       }

     return super.onTouchEvent(event);
     }

}

*res/layout/main.xmlの変更後の全ソース:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
 android:id="@+id/myTextView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<TextView
 android:id="@+id/myTextPosition"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/position"
    />
</LinearLayout>

*res/values/strings.xmlの変更後の全ソース:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, SampleTwo!</string>
    <string name="app_name">Sample02</string>
    <string name="position">X:00 Y:00</string>
</resources>

その他のソースコードは、ブログ記事「char配列を、String変数に変換する」のサンプルと同じです。

  • 広告

* RSS FEED