2012年10月26日金曜日

ActionBarにドロップダウンリストを表示する

Android3.xから追加されたActionBarはナビゲーションモードを切りかえることで、
ActionBarにタブを表示することができました。
このナビゲーションモードには、別にドロップダウンリストを表示するためのモードがあります。
本エントリではActionBarのナビゲーションモードを変更し、ドロップダウンリストを利用する方法と、ActionBarでSearchViewを利用する方法を紹介します。

紹介に利用するサンプルは、ActionBarにドロップダウンリストとSearchViewを表示しています。
SearchViewは表示されているListViewの内容をインクリメンタルサーチの様にフィルタリング
する為に利用しています。
ドロップダウンリストはSearchViewでのフィルタリングのOn/Offを切り替える為に利用しています。

ActionBarでドロップダウンリストを利用する

ActionBarのナビゲーションモードを変更し、ドロップダウンリストを使用するためには、
以下の手順をふむ必要があります。

  1. List表示するアイテムの作成
  2. ActionBarのナビゲーションモードをActionBar.NAVIGATION_MODE_LISTに変更する
  3. ActionBar.OnNavigationListenerを作成、設定する

上記手順にそって、解説を進めていきます。

1.List表示するアイテムの作成

まずList表示を行うアイテムを作成します。
本エントリで紹介する方法以外にも、表示するアイテムの設定方法は色々あります。
その他の設定方法は以下の記事を参考にどうぞ。

Spinnerクラスを使ってコンボボックスを表示する

サンプルでは、「FilterMode」と「Non-FilterMode」を選択させるためにドロップダウンリストを利用していますので、それら二つを表示するアイテムとして、strings.xml内にstring-arrayとして作成します。

■strings.xml

1
2
3
4
5
6
7
<resources>
    // 省略...
    <string-array name="action_list">
        <item>FilterMode</item>
        <item>Non-FilterMode</item>
    </string-array>
</resources>

3行目でString配列の名前をaction_listとして宣言しています。
後に利用することになるので覚えておきましょう。

2.ActionBarのナビゲーションモードをActionBar.NAVIGATION_MODE_LISTに変更する

ActionBarのナビゲーションモードを変更することで、ドロップダウンリスト表示を行う様に設定します。
ナビゲーションモードの変更にはActionBarクラスのsetNavigationModeメソッドを利用します。

3.ActionBar.OnNavigationListenerを作成、設定する

ドロップダウンリストのアイテムを選択した時に呼び出されるListenerを用意します。
用意するListenerはActionBar.OnNavigationListenerです。

用意したListenerをActionBarクラスのsetListNavigationCallbacksメソッドを利用して
設定することで、Callbackの登録が完了します。

ここまでのドロップダウンリストを利用するための、一連のサンプルコードは以下の様になります。
ナビゲーションアイテムを選択した時に呼び出されるonNavigationItemSelectedメソッドには、
選択したアイテムのIdを保持するための処理を実装しています。
保持したIdは後述のSearchViewにおいて利用しています。

■SearchViewSampleActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class SearchViewSampleActivity extends Activity implements
        OnQueryTextListener, ActionBar.OnNavigationListener {
    // 省略...
    private SpinnerAdapter mSpinnerAdapter = null;
    private String[] modeArray = null;
    private int MODE = 0;
    MyFragment current = null;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        ActionBar mActionBar = getActionBar();
        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
 
        mSpinnerAdapter = ArrayAdapter.createFromResource(this,
                R.array.action_list,
                android.R.layout.simple_spinner_dropdown_item);
 
        mActionBar.setListNavigationCallbacks(mSpinnerAdapter, this);
 
        // arraylistの設定(strings.xmlの配列を取得)
        modeArray = getResources().getStringArray(R.array.action_list);
 
        // ListViewを表示するFragment
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        current = new MyFragment();
        ft.replace(R.id.frameLayout1, current, FRAGMENT_TAG);
        ft.commit();
 
    }
 
    @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
        Log.d(TAG, "select item = " + modeArray[itemPosition]);
        MODE = itemPosition;
 
        return true;
    }

2行目でActionBar.OnNavigationListenerをimplimentsしています。
コールバックとして呼び出されるonNavigationItemSelectedメソッドを35行目以降で実装しています。
15行目でナビゲーションモードを変更しています。
17行目では、ArrayAdapterクラスのcreateFromResourceメソッドを利用し、
strings.xmlに作成したaction_listをSpinnerAdapterとして取得しています。
21行目では取得したSpinnerAdapterの設定とコールバックの登録をsetListNavigationCallbacksメソッドで行っています。

SearchViewをActionBarで利用する

TechBoosterでは、SearchViewの利用方法を以下記事で紹介していますので、
詳細な利用方法はそちらを参照ください。

SearchViewを使用してListViewのアイテムにフィルターをかける
※参照先の記事はプレビュー版SDKをベースに作成しているため、SearchView.OnQueryChangeListener
を利用していますが、正しくはOnQueryTextListenerとなります。

通常のSearchViewを利用する場合と異なる点は以下の一点です。

  • SearchViewをActionBarへアクションビューとして作成する

ActionBarにWidgetを配置することをActionViewと呼びます。
※ActionViewについて、詳しくはリンク先(AndroidDevelopers)を参照ください。

ActionBarにアクションビューを設定する方法は、xmlファイルにおいてandroid:actionViewClass属性を利用します。
サンプルでは、アクションビューにSearchViewを設定しているため、以下の様にxmlファイルに宣言しています。

■action_menu.xml

1
2
3
4
    <item android:id="@+id/search_view" android:icon="@android:drawable/ic_menu_search"
    android:title="Search" android:showAsAction="always" android:actionViewClass="android.widget.SearchView" />
</menu>

3行目にてandroid:actionViewClass属性を設定しています。
actionViewClass属性の設定にはクラスパスを省略せずに指定する必要があります。

アクションビューの設定は、アクションアイテムをActionBarへ設定する場合と同様に、
onCreateOptionsMenuメソッドにおいて、上記で作成したxmlファイルを読み込み設定します。

サンプルSearchViewに対する処理はSearchViewを使用してListViewのアイテムにフィルターをかける
と同様の内容ですので、詳細はそちらを参照ください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // action barの設定
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.action_menu, menu);
 
    // SearchViewの設定
    SearchView searchView = (SearchView) menu.findItem(R.id.search_view)
            .getActionView();
    searchView.setOnQueryTextListener(this);
 
    return true;
}
 
/**
 * SearchViewに入力するたびに入力される
 */
@Override
public boolean onQueryTextChange(String newText) {
    ActionBar ab = getActionBar();
 
    // FilterModeの時のみListViewにFileterをかける
    if (modeArray[MODE].equals("FilterMode")) {
        if (TextUtils.isEmpty(newText)) {
            current.clearFilter();
        } else {
            current.setFilter(newText.toString());
        }
    }
    return true;
}
 
/**
 * SearchViewのSubmitを押下したときに呼び出される
 */
@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}
 
private class MyFragment extends ListFragment {
    private final String[] rows = { "abc", "aab", "aac", "aaa", "abb",
            "acc", "cab", "ccc", "bbb" };
 
    MyFragment() {
    }
 
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
 
        // ListViewにFilterをかけれるようにする
        getListView().setTextFilterEnabled(true);
 
        // ListViewに表示するItemの設定
        setListAdapter(new ArrayAdapter(getActivity(),
                android.R.layout.simple_list_item_1, rows));
    }
 
    /**
     * ListViewにFilterをかける
     * @param s
     */
    public void setFilter(String s){
        getListView().setFilterText(s);
    }
 
    /**
     * ListViewのFilterをClearする
     */
    public void clearFilter(){
        getListView().clearTextFilter();
    }
}

5行目で、inflateメソッドを利用して、action_menu.xmlで定義したアクションビューを読み込んでいます。
8行目〜10行目では、アクションビューとして設定したSearchViewを取得し、Listener登録を行っています。
27行目にて、ListViewにFilterを設定しています。
41行目以降はListViewを表示するために利用しているListFragmentになります。

0 件のコメント:

コメントを投稿