タイトル画面には、それぞれのモードへ行くためのボタンが必要だね。
フツウにボタンを配置してもいいんだけど、それだとタイトル画面専用になっちゃう。
別にかまわないんだけど、せっかくなんで、汎用選択肢メニューとして作ってみた。
仕 様
- 選択肢ボタンは、選択肢専用 ViewGroup に属する。
- ボタン生成と共に、それぞれへユニークなIDがふられる。
- ボタンを押されると、それぞれのIDをハンドラ へ送る。
- ハンドラはすぐにViewGroup とボタンを非表示にする。
で、メニュー(ハンドラ) が保持するIDを見れば、なにが選択されたかわかる。
もしくは、メニューからリスナーへの通知にしてもいいね。
…って、ListView そのものじゃん! Σ
じゃ、ListView をベースに作ればいいか…と、ちょっとやってみたがうまくいかない。
どうもXMLを使わないと面倒らしい…。
「AndroidでListView」
XMLを使わない場合だと、自前でBaseAdapterクラスを拡張して、getView()の中でList内の要素を生成しないといけないらしい
おそらく、BaseAdapter がボタンからの通知を統括してたりするんだろうね。
当初の予定どおり、自前で作るとするか。
まぁ、Open & Close のエフェクトとかを考えたら、その方が融通効きそうだし。
プロトタイプ
で、こんな感じで作ってみた。
package com.migimaki.android; import android.content.Context; import android.widget.LinearLayout; import android.view.Gravity; import android.graphics.Color; import android.widget.TextView; import android.widget.Button; import android.view.View; import android.view.View.OnClickListener; import android.util.Log; public class SelectMenu extends LinearLayout implements OnClickListener{ private Context context = null; private onSelectListener _listener = null; //リスナー // public int chois = 1; // 選択回数カウンター。残り値分、選択可能。 public boolean selected = false; // 選択されたか? public int select_id = -1; // 選択されたボタンID //-- //== public SelectMenu ( Context c ){ super( c ); context = c; //-- setOrientation(LinearLayout.VERTICAL); // View配置設定 : 縦並び } // init & make Menu public void init( String menuMes, String butName[] ){ chois = 1; selected = false; select_id = -1; //-- setGravity(Gravity.CENTER); // センター配置 // Padding // setPadding( 100, 100, 200, 200 ); // setPadding( -1, -1, -1, -1 ); // Padding 未設定の状態に初期化 //-- // メニュー・メッセージ addMes( menuMes ); // ボタン作成 for ( int i=0; i<butName.length; i++ ){ addButton( i, butName[i] ); } // setVisibility( View.VISIBLE ); } // make Text Mes public void addMes( String mesStr ){ TextView mes = new TextView( context ); mes.setText( mesStr ); mes.setBackgroundColor(Color.argb( 128, 0, 0, 255 )); // 背景色設定 mes.setHeight(40); // 高さ設定 mes.setTextSize(20.0f); // フォントサイズ mes.setGravity(Gravity.CENTER); // センター表示 addView(mes); } // make Button public void addButton( int id, String butName ){ Button but = new Button( context ); but.setId( id ); but.setText( butName ); // mes.setBackgroundColor(Color.argb( 128, 0, 0, 255 )); // 背景色設定 mes.setHeight(40); // 高さ設定 mes.setTextSize(20.0f); // フォントサイズ mes.setGravity(Gravity.CENTER); // センター表示 addView(but); but.setOnClickListener( this ); // onClick の設定 // Log.d("TEST", "add but(" +id +")"+" : " +but.getId() ); } // close : remove All Views public void close( ){ removeAllViews(); } // Event : click public void onClick( View but ){ if ( chois > 0 ){ selected = true; select_id = but.getId(); if ( _listener != null ){ _listener.onMenuSelected( select_id ); // イベントの通知( -> Activty ) } chois--; //-- // 選択されたボタン以外を非表示にする。 if( chois <= 0 ){ int child = getChildCount(); for ( int i=1; i<child; i++ ){ if( i != ( select_id +1 ) ){ getChildAt( i ).setVisibility( View.INVISIBLE ); } } } //-- } //-- // Log.d("TEST", "Who click? : " +but.getId() +" select_id : " +select_id ); } //////////////////////////////////////////////////////////////// // イベントの通知先 public interface onSelectListener{ public void onMenuSelected( int select_id ); } // リスナーの登録 public void setOnSelectListener( onSelectListener listener ){ _listener = listener; } //////////////////////////////////////////////////////////////// }
●SelectMenu のオブジェクトを生成後、表示したいViewGroup にadd すれば使用できる。
●表示位置とボタンの横幅は、setPadding で設定する。
setPadding はLinearLayout に元々あるmethod なので、オブジェクトに対しても設定できるよ。
●init() で、メニュー・メッセージと各ボタン名の設定。
method を実行すると、メッセージのTextViewとボタンを生成して、メニューを表示する。
●選択肢が決定されると、ボタンのIDがselect_id に保持される。
また、リスナー登録しておくと、select_id を通知してくれる。
●close() で、メニューを非表示にする。
すべてのメッセージとボタンをLinearLayout から削除する。
オブジェクトは生きてるので、init() すれば新しいメニューが表示されるよ。
●ちょっとお遊びで、chois という変数をつけてみた。
chois回数分だけ、ボタンを押せる。
正解を選ぶとか、正しい順番を押させるとか、…そんな使い方。
課 題
・ボタンの外観 今はデフォなので味気なし。 カーソルと、押された時の反応も変えるべし。 ・ボタン・サイズ 文字サイズと共に、今は固定。 文字列に合わせて変わる、指定設定できるようにする。 ・Open & Close エフェクト パッと表示されるだけじゃ味気ない。 なにかエフェクトをつけよう。
それと、ソースの洗練もね。(w