やり方自体は、SpinnerAdapterをActionBar.setListNavigationCallbacks()の引数に指定すれば良いのですが、公式ドキュメントに書いてあるサンプルは選択できる項目が予め決まっているResourceファイルから作るので、コーディングは最小限で済む代わりに動的に選択項目を作りたい場合などはこの方法は使えません。
で、軽くググって見た限りでは世の中にほとんどサンプルが無くて、ちょっと苦労したのでここに簡単にまとめておこうかと思います。そのうちTechBoosterさんにちゃんとした記事が載るような 気がするので、その時はこんないい加減なblogよりもそちらの方をどうかご参照ください(笑
SpinnerAdapterとして実装しないといけないインターフェースは下記
メソッド名 | 概要 |
int getCount() | 選択項目の個数を返す |
Object getItem(int position) | position位置の要素を返す |
long getItemId(int position) | position位置の要素のIDを返す |
int getItemViewType(int position) | getView()で作成されるViewのタイプを返す |
View getView(int position, View convertView, ViewGroup parent) | position位置のViewを返す |
int getViewTypeCount() | Viewのタイプ数を返す |
boolean hasStableIds() | アイテムのIDがデータによらず安定しているか? |
boolean isEmpty() | リストが空か? |
void registerDataSetObserver(DataSetObserver observer) | データの変更を検出するオブザーバーを設定 |
void unregisterDataSetObserver(DataSetObserver observer) | データの変更を検出するオブザーバーの設定を解除 |
View getDropDownView(int position, View convertView, ViewGroup parent) | drop-downのpopupに表示されるViewを返す |
ListViewなんかでAdapterに馴染みがあればほとんどのメソッドに関してはご存知かと思いますが、ここでの肝はgetView()とgetDropDownView()です。
メソッド名からもわかる?ように、getView()がActionBarに選択項目として描画されるViewを返し、getDropDownView()がdrop-downのポップアップに描画されるViewを返す為のメソッドです。
簡単にテキストだけ描画されるようなメニューならメソッド内でTextViewを作って返してやればいいようなものなんですが、getDropDownView()がどうにもうまく行きませんでした。コンパイルまでは問題無いのですが、ランタイム時にエラーが出てアプリが死にます。
LogCatのログを見てみると、どうもLayoutの型変換でエラーが出ているようなのですが、いろいろ試してもうまく行かないので最終的にはlayoutのxmlファイルを定義して、LayoutInflaterでViewを作成するようにしました。
ということで、最終的に以下のようなコードでうまくいったのですが、何か勘違いしているかも知れませんので、識者の方からアドバイスをいただけると幸いです。
SampleActivity.java
public class SampleActivity extends Activity implements OnNavigationListener { private ArrayListmenuList = new ArrayList (); private LayoutInflater mInflater; private ActionBar mActionBar; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mActionBar = getActionBar(); mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); mActionBar.setListNavigationCallbacks(new mSpinnerAdapter(), this); // drop-downメニューのデータを自由に作成 // ここではコード上の文字列を設定してますが // 例えば、IntentのBundleで受け取ったデータ // をもとに作成してもいいでしょう menuList.add("One"); menuList.add("Two"); menuList.add("Three"); } private class mSpinnerAdapter implements SpinnerAdapter { @Override public int getCount() { return menuList.size(); } @Override public Object getItem(int position) { return menuList.get(position); } @Override public long getItemId(int position) { // とりあえずpositionをIDとして返す return position; } @Override public int getItemViewType(int position) { // 何を設定すればよいのかわからないのでとりあえず // IGNORE_ITEM_VIEW_TYPEを返す return IGNORE_ITEM_VIEW_TYPE; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { // getView()はこれでうまく行く convertView = new TextView(mContext); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); convertView.setLayoutParams(params); } ((TextView) convertView).setText(menuList.get(position)); return convertView; } @Override public int getViewTypeCount() { return 1; } @Override public boolean hasStableIds() { return false; } @Override public boolean isEmpty() { return false; } @Override public void registerDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } @Override public void unregisterDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { if (convertView == null) { // getDropDownView()はうまくいかないので // LayoutInflaterでViewを作成 convertView = mInflater.inflate(R.layout.dropdown_menu, parent, false); } ((TextView) convertView.findViewById(R.id.dropdown_menu_item)).setText(menuList.get(position)); return convertView; } } @Override public boolean onNavigationItemSelected(int itemPosition, long itemId) { // itemPositionの選択に応じた処理 return true; } }
dropdown_menu.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/dropdown_menu_item" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
0 件のコメント:
コメントを投稿