SDKでダイアログ表示2013/12/26

今回は、ダイアログの表示を行います。
ダイアログは SDKの機能を使うので native側のプログラムではないのですが、共通部分でいろいろ変更点があったので挙げておきます。

ダイアログの表示には、DialogFragmentを使用します。
Dialogを直接 create(), show()でもダイアログは表示されますが、アクティビティがダイアログの再生成をするとかで DialogFragmentを使うべき…らしいです。


BaseActivity.java
/********************
    アクティビティ
 ********************/
public class BaseActivity extends FragmentActivity
{
	static {
		System.loadLibrary("native");
    }


	public final static int		KEY_BACK	= 1;		// バックキー
	public final static int		KEY_YES		= 2;		// ダイアログ用
	public final static int		KEY_NO		= 3;

基本アクティビティの変更点です。
Activityではなく FragmentActivityを継承しています。
FragmentActivityを使うためにプロジェクトには android-support-v4.jarを追加しています。

また、アプリ側で汎用的に使えるように KEY_YESと KEY_NOを定義しています。


AppActivity.java
package app;

import sys.BaseActivity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;


/********************
    アクティビティ
 ********************/
public class AppActivity extends BaseActivity
{
	static public AppActivity	app;


	/**********
	    開始
	 **********/
	@Override
	protected void	onCreate(Bundle _savedInstanceState)
	{
		super.onCreate(_savedInstanceState);

		app = this;
	}


	/**************
	    終了確認
	 **************/
	static
	public void		open_dialog()
	{
		ExitDialogFragment	_dlg = new ExitDialogFragment();			// 終了確認ダイアログ

		_dlg.show(app.getSupportFragmentManager(), "dialog");
	}

	/********************
	    終了ダイアログ
	 ********************/
	public static class ExitDialogFragment extends DialogFragment
	{
		@Override
		public Dialog	onCreateDialog(Bundle savedInstanceState)
		{
			AlertDialog.Builder		builder = new AlertDialog.Builder(getActivity());

			builder.setMessage("アプリを終了しますか");
			builder.setPositiveButton("終了",
				new DialogInterface.OnClickListener()
				{
					@Override
					public void		onClick(DialogInterface dialog, int which)
					{
						key_status = KEY_YES;
					}
				});
			builder.setNegativeButton("キャンセル",
				new DialogInterface.OnClickListener()
				{
					@Override
					public void		onClick(DialogInterface dialog, int which)
					{
						key_status = KEY_NO;
					}
				});

			return	builder.create();
		}
	}
}

/***************** End of File ***************************************************/

java側で独自の処理があるので、BaseActivityを継承した AppActivityを作成しています。
nativeから open_dialog()を呼んでダイアログを表示します。

ExitDialogFragmentが使用するダイアログのクラスです。
ボタンを押したときは key_statusに値を入れて BaseActivityの処理で native側に送っています。


AppMain.cpp
/************************
    終了確認ダイアログ
 ************************/
static
void	open_dialog(void)
{
	JNIEnv*		env;
	Bool		attach_flag = FALSE;

	if ( sys::g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6) < 0 ) {
		if ( sys::g_JavaVM->AttachCurrentThread(&env, NULL) < 0 ) {
			return;
		}
		attach_flag = TRUE;
	}

	jclass	clazz = env->FindClass("app/AppActivity");

	if ( clazz ) {
		jmethodID	mid = env->GetStaticMethodID(clazz, "open_dialog", "()V");

		if ( mid ) {
			env->CallStaticVoidMethod(clazz, mid);
		}
	}
	if ( attach_flag ) {
		sys::g_JavaVM->DetachCurrentThread();
	}
}

/******************************
    稼働
		戻り値	アプリ続行か
 ******************************/
Bool	update_app(void)
{
	switch ( phase ) {
	  case PHASE_MAIN :				// メイン
		cnt++;
		if ( sys::key_status == sys::KEY_BACK ) {		// バックキー
			open_dialog();								// 終了確認ダイアログ
			phase = PHASE_DIALOG;
		}
		break;

	  case PHASE_DIALOG :			// 終了確認ダイアログ
		switch ( sys::key_status ) {
		  case sys::KEY_YES :
			sys::Renderer::fade_out(60);
			end_cnt = 60;
			phase = PHASE_EXIT;
			break;

		  case sys::KEY_NO :
			phase = PHASE_MAIN;
			break;
		}
		break;

	  case PHASE_EXIT :				// 終了
		if ( --end_cnt == 0 ) {
			return	FALSE;								// アプリ終了
		}
		break;
	}


	sprite[SPR_PHOTO].draw(0.0f, 0.0f);					// 背景
	for (int i = 0; i < 4; i++) {						// ビー玉
		int		t = ((cnt + i*15) % 60) - 30;

		sprite[SPR_BALL_BLUE + i].draw(((i*180 + cnt*4) % 720) - 360, 400 - (30*30 - t*t)/2);
	}

	return	TRUE;
}

native側のサンプルです。
バックキーを押すと、ダイアログを表示するようになっています。


ダイアログ


プロジェクト一式は、こちらです。