【Unity】Androidの選択ダイアログを使う 
2017/10/28 Sat [edit]
Unity で Android の標準的な選択ダイアログ(AlertDialog)を利用できるプラグインを作ってみた。元々は音声認識の候補を絞りこむ目的で作ったのだけど、これ自前でUI作らなくていいからかなり便利だね。今回はとりあえず、単一選択で確認ボタンなし、単一選択で確認ボタンあり、複数選択の3種類を作っておいた。戻り値をアイテムの文字列かインデクス(※ただしどちらも文字列型)で返すか、アイテムごとに戻り値を指定するか(11/06 オーバーロード追加)を引数で変更できるようにしておいたので、色々と利用できると思う。
内容的にはAndroidの基本機能を利用するプラグインのアップデート版。一部仕様変更した部分もあるが(詳細は更新履歴を参照)、基本的にはそのまま使えるので旧バージョンがある場合は上書きでも構わないと思う。プラグイン自体のセットアップは以前の記事を参照して欲しい。自分で作りたい場合は簡略化したものだが、今回も元の Java コードを書いておくので挑戦してみるのも良いだろう(※Java コードは解説用に一部抜粋・省略したものであって、そのままコピペでは使えないことに注意)。
|
■単一選択ダイアログ①を使う(AlertDialog) [確認ボタン無し]
■単一選択ダイアログ②を使う(AlertDialog) [確認ボタン有り]
■複数選択ダイアログを使う(AlertDialog)
■更新履歴
(※) Unity 5.6.3p1 / AndroidStudio 2.3.3 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認
■単一選択ダイアログ①を使う(AlertDialog) [確認ボタン無し]

●Unity から Android の AlertDialog を使う C# コード(単一選択ダイアログ①)
using FantomLib;
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidPlugin.ShowSelectDialog(title, items[], callbackGameObject, callbackMethod, resultIsIndex, style);
#endif
●プラグイン内の対応する Java コード
import android.app.AlertDialog;
import android.content.DialogInterface;
import static com.unity3d.player.UnityPlayer.UnitySendMessage;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
UnitySendMessage(callbackGameObject, callbackMethod, resultIsIndex ? String.valueOf(which) : items[which]);
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context, styleId);
builder.setTitle(title)
.setItems(items, listener)
.show();
これは文字列型配列の要素を列挙し、各項目をタップすることにより選択するダイアログ(AlertDialog)である。後述する「単一選択ダイアログ2」と内容的には同じになるが、こちらには確認ボタンが無い(→押すとすぐに値が返る)。戻値は「resultIsIndex」が false(デフォルト) のとき「選択された項目の文字列」が返り、「resultIsIndex」が true のときは「選択された項目のインデクス(0~n-1 ※ただし文字列型なので注意)」がヒエラルキーにある GameObject 名(callbackGameObject)のメソッド(callbackMethod)に文字列で返ってくる。また Android のダイアログの場合、範囲外をクリックするとダイアログが消えるが、その場合は何も返って来ない。コールバックするメソッドのシグネチャは文字列型(string)固定になる(というより基本的にネイティブ間のメッセージやりとりは全て文字列型と考えて良い→受け取り側で適切に変換して使う)。
ダイアログにはスタイル(テーマ)を当てられるようにしてある。省略=空文字("")のときはアクティビティのテーマと同じものになる。スタイルの引数は "android:Theme.DeviceDefault.Dialog.Alert" のように、名前のアンダバー("_")をドット(".")に変えたものを指定する。端末の API Level によって使えるものとそうでないものがあるので、アプリのビルドの API Level に合わせて指定する必要があるので注意。
(参考)R.style.theme
サンプルコードは「Assets/_Test/Scripts/SpeechRecognizerTest.cs」の「ResultSpeechRecognizer()」「OnResult()」あたりを見て欲しい。
■単一選択ダイアログ②を使う(AlertDialog) [確認ボタン有り]

●Unity から Android の AlertDialog を使う C# コード(単一選択ダイアログ②)
using FantomLib;
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidPlugin.ShowSingleChoiceDialog(title, items[], checkedItem, callbackGameObject, callbackMethod, resultIsIndex,
okCaption, cancelCaption, style);
#endif
●プラグイン内の対応する Java コード
import android.app.AlertDialog;
import android.content.DialogInterface;
import static com.unity3d.player.UnityPlayer.UnitySendMessage;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
if (which >= 0) {
checkedItem = which;
}
else if (which == DialogInterface.BUTTON_POSITIVE) { //-1
UnitySendMessage(callbackGameObject, callbackMethod, resultIsIndex ? String.valueOf(checkedItem) : items[checkedItem]);
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context, styleId);
builder.setTitle(title)
.setSingleChoiceItems(items, checkedItem, listener)
.setPositiveButton(okCaption, listener)
.setNegativeButton(cancelCaption, null)
.show();
こちらも文字列型配列の要素を列挙し、各項目をタップすることにより選択するダイアログ(AlertDialog)である。前述した「単一選択ダイアログ1」と内容的には変わらないが、こちらには確認ボタンがある(→「はい」ボタンで値が返る)。戻値は「resultIsIndex」が false(デフォルト) のとき「選択された項目の文字列」が返り、「resultIsIndex」が true のときは「選択された項目のインデクス(0~n-1 ※ただし文字列型なので注意)」がヒエラルキーにある GameObject 名(callbackGameObject)のメソッド(callbackMethod)に文字列で返ってくる。またキャンセルボタンを押した時と、Android のダイアログの場合、範囲外をクリックするとダイアログが消えるが、その場合は何も返って来ない。コールバックするメソッドのシグネチャは文字列型(string)固定になる(というより基本的にネイティブ間のメッセージやりとりは全て文字列型と考えて良い→受け取り側で適切に変換して使う)。
ダイアログにはスタイル(テーマ)を当てられるようにしてある。省略=空文字("")のときはアクティビティのテーマと同じものになる。スタイルの引数は "android:Theme.DeviceDefault.Dialog.Alert" のように、名前のアンダバー("_")をドット(".")に変えたものを指定する。端末の API Level によって使えるものとそうでないものがあるので、アプリのビルドの API Level に合わせて指定する必要があるので注意。
(参考)R.style.theme
サンプルコードは「Assets/_Test/Scripts/SpeechRecognizerTest.cs」の「ResultSpeechRecognizer()」「OnResult()」あたりを見て欲しい。
■複数選択ダイアログを使う(AlertDialog)

●Unity から Android の AlertDialog を使う C# コード(複数選択ダイアログ)
using FantomLib;
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidPlugin.ShowMultiChoiceDialog(title, items[], checkedItems[], callbackGameObject, callbackMethod, resultIsIndex,
okCaption, cancelCaption, style);
#endif
●プラグイン内の対応する Java コード
import android.app.AlertDialog;
import android.content.DialogInterface;
import static com.unity3d.player.UnityPlayer.UnitySendMessage;
DialogInterface.OnMultiChoiceClickListener listener = new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
}
};
DialogInterface.OnClickListener listenerOK = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
String str = "";
for (int i = 0; i < checkedItems.length; i++) {
if (checkedItems[i]) {
if (str.length() > 0)
str += "\n";
if (resultIsIndex)
str += String.valueOf(i);
else
str += items[i];
}
}
UnitySendMessage(callbackGameObject, callbackMethod, str);
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context, styleId);
builder.setTitle(title)
.setMultiChoiceItems(items, null, listener)
.setPositiveButton(okCaption, listenerOK)
.setNegativeButton(cancelCaption, null)
.show();
これは文字列型配列の要素を列挙し、各項目をチェックすることにより複数選択するダイアログ(AlertDialog)である。戻値は「resultIsIndex」が false(デフォルト) のとき「選択された項目の文字列」が返り、「resultIsIndex」が true のときは「選択された項目のインデクス(0~n-1 ※ただし文字列型なので注意)」がヒエラルキーにある GameObject 名(callbackGameObject)のメソッド(callbackMethod)に改行("\n")で結合されて文字列で返ってくる。またキャンセルボタンを押した時と、Android のダイアログの場合、範囲外をクリックするとダイアログが消えるが、その場合は何も返って来ない。コールバックするメソッドのシグネチャは文字列型(string)固定になる(というより基本的にネイティブ間のメッセージやりとりは全て文字列型と考えて良い→受け取り側で適切に変換して使う)。
ダイアログにはスタイル(テーマ)を当てられるようにしてある。省略=空文字("")のときはアクティビティのテーマと同じものになる。スタイルの引数は "android:Theme.DeviceDefault.Dialog.Alert" のように、名前のアンダバー("_")をドット(".")に変えたものを指定する。端末の API Level によって使えるものとそうでないものがあるので、アプリのビルドの API Level に合わせて指定する必要があるので注意。
(参考)R.style.theme
サンプルコードは「Assets/_Test/Scripts/SpeechRecognizerTest.cs」の「ResultSpeechRecognizer()」「OnResult()」あたりを見て欲しい。
■更新履歴
今回のアップデートを簡単に説明しておくと以下のようになる。[⇒全体の更新履歴はこちら]
・選択ダイアログ(単一/複数:AlertDialog/SingleChoice/MultiChoice)の追加。
・テキスト読み上げ(TextToSpeech)の追加。
・音声認識の戻り値の区切り文字(改行("\n"))が最後に付かないようにした。
17/11/06(機能追加)
・[追加]の各アイテムごとに戻り値を指定できるオーバーロードを追加。(※全更新履歴より)
具体的に音声認識の戻り値の区切り文字(改行("\n"))については、以前は "項目0\n項目1\n項目2\n" で返ってきていたのが、"項目0\n項目1\n項目2" のように最後には改行が付かなくなったということだ。というのは、選択ダイアログに音声認識の結果をそのまま Split('\n') で突っ込めた方が楽だと考えたからだ(Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries) でも良いが冗長に感じたので)。それ以外は特に仕様変更してないので、以前のバージョン上書きでも問題なく動作すると思う。
実際の Java コードは色々値をチェックしたり条件分岐したり、高速化のためにキャッシュしたり、StringBuilderを使ったりしているが、長くなるのでここでは簡略化したものを書いてあると考えて欲しい。Java を知っている人なら中身は非常に簡単なものばかりだとわかるだろう。AndroidStudio を使ったことあるなら AAR プラグインをビルドするのは簡単なので、挑戦してみるのも良いかも知れない。
※この記事のUnityアセットはプラグインとして配布されています。
(関連記事)
【Unity】Androidでカスタマイズしたダイアログを動的生成できるプラグインを作ってみた
【Unity】Androidでスイッチで設定を変更するダイアログを使う
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】Androidでチェックボックス付きのアラートダイアログ(AlertDialog)を使う
【Unity】Androidで日付・時刻選択ダイアログ(DatePicker, TimePicker)を使う
【Unity】Androidで数値・半角英数・パスワード入力ダイアログを使う
【Unity】Androidでテキスト入力ダイアログを使う
【Unity】Androidのテキスト読み上げ(TextToSpeech)を使う
【Unity】Androidのハードウェア音量操作・ハードウェアキーの無効化をする
【Android】【Java】音声入力(音声認識)で文字列を取得する
【Android】【Java】AlertDialog を使ってみる
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/274-0af82e51
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |