v7 appcompat サポート ライブラリ Toolbar
には、ユーザーがアプリを操作するためのさまざまな方法が用意されています。前のレッスンでは、アクション(ボタンまたはメニュー項目)を定義する方法について説明しました。このレッスンでは、2 つの汎用コンポーネントを追加する方法について説明します。
- アクション ビューは、アプリバー内に豊富な機能を提供するアクションです。たとえば検索アクション ビューを使用すると、ユーザーはアクティビティまたはフラグメントを変更することなく、アプリバーに検索テキストを入力できます。
- アクション プロバイダは、独自のカスタマイズされたレイアウトを持つアクションです。 アクションは、最初はボタンまたはメニュー項目として表示されますが、ユーザーがアクションをクリックすると、定義したい方法でアクション プロバイダがアクションの動作を制御します。たとえばアクション プロバイダは、メニューを表示することでクリックに対応する場合があります。
Android サポート ライブラリには、特殊なアクション ビューとアクション プロバイダ ウィジェットがいくつか用意されています。たとえば、SearchView
ウィジェットは検索クエリを入力するためのアクション ビューを実装し、ShareActionProvider
ウィジェットは他のアプリと情報を共有するためのアクション プロバイダを実装します。独自のアクション ビューとアクション プロバイダを定義することもできます。
アクション ビューの追加
アクション ビューを追加するには、アクション ボタンの追加で説明しているように、ツールバーのメニュー リソースに<item>
要素を作成します。次の 2 つの属性のいずれかを <item>
要素に追加します。
-
actionViewClass
: アクションを実装するウィジェットのクラス。 -
actionLayout
: アクションのコンポーネントを記述するレイアウト リソース。
showAsAction
属性を "ifRoom|collapseActionView"
または "never|collapseActionView"
のいずれかに設定します。collapseActionView
フラグは、ユーザーがウィジェットを操作していないときにウィジェットを表示する方法を示します。ウィジェットがアプリバーにある場合、アプリはウィジェットをアイコンとして表示する必要があります。ウィジェットがオーバーフロー メニューにある場合、アプリはウィジェットをメニュー項目として表示する必要があります。ユーザーがアクション ビューを操作すると、アプリバーいっぱいに展開されます。
たとえば、次のコードは SearchView
ウィジェットをアプリバーに追加します。
<item android:id="@+id/action_search" android:title="@string/action_search" android:icon="@drawable/ic_search" app:showAsAction="ifRoom|collapseActionView" app:actionViewClass="android.support.v7.widget.SearchView" />
ユーザーがウィジェットを操作していない場合、アプリは android:icon
で指定されたアイコンとしてウィジェットを表示します。(アプリバーに十分なスペースがない場合、アプリはオーバーフロー メニューにアクションを追加します。)ユーザーがアイコンまたはメニュー項目をタップすると、ウィジェットがツールバーいっぱいに展開され、ユーザーが操作できるようになります。

図 1. ユーザーがアクション ビューのアイコンをクリックすると、ビューの UI がツールバーいっぱいに表示されます。
アクションを構成する必要がある場合は、アクティビティの onCreateOptionsMenu()
コールバックで構成します。getActionView()
メソッドを呼び出すことで、アクション ビューのオブジェクト参照を取得できます。たとえば次のコードは、前のコード例で定義した SearchView
ウィジェットのオブジェクト参照を取得します。
Kotlin
override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.main_activity_actions, menu) val searchItem = menu?.findItem(R.id.action_search) val searchView = searchItem?.actionView as SearchView // Configure the search info and add any event listeners... return super.onCreateOptionsMenu(menu) }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_activity_actions, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) searchItem.getActionView(); // Configure the search info and add any event listeners... return super.onCreateOptionsMenu(menu); }
アクション ビューの展開への対応
アクションの <item>
要素に collapseActionView
フラグがある場合、ユーザーがアクション ビューを操作するまで、アプリはアクション ビューをアイコンとして表示します。ユーザーがアイコンをクリックすると、onOptionsItemSelected()
の組み込みハンドラがアクション ビューを展開します。アクティビティ サブクラスが onOptionsItemSelected()
メソッドをオーバーライドする場合、オーバーライド メソッドは super.onOptionsItemSelected()
を呼び出して、スーパークラスがアクション ビューを展開できるようにする必要があります。
アクションが展開されたときまたは折りたたまれたときに何かを行う場合は、MenuItem.OnActionExpandListener
を実装するクラスを定義し、そのクラスのメンバーを setOnActionExpandListener()
に渡せます。たとえば、アクション ビューが展開されているか折りたたまれているかに基づいて、アクティビティを更新できます。次のスニペットは、リスナーを定義して渡す方法を示しています。
Kotlin
override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.options, menu) // ... // Define the listener val expandListener = object : MenuItem.OnActionExpandListener { override fun onMenuItemActionCollapse(item: MenuItem): Boolean { // Do something when action item collapses return true // Return true to collapse action view } override fun onMenuItemActionExpand(item: MenuItem): Boolean { // Do something when expanded return true // Return true to expand action view } } // Get the MenuItem for the action item val actionMenuItem = menu?.findItem(R.id.myActionItem) // Assign the listener to that action item actionMenuItem?.setOnActionExpandListener(expandListener) // Any other things you have to do when creating the options menu... return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.options, menu); // ... // Define the listener OnActionExpandListener expandListener = new OnActionExpandListener() { @Override public boolean onMenuItemActionCollapse(MenuItem item) { // Do something when action item collapses return true; // Return true to collapse action view } @Override public boolean onMenuItemActionExpand(MenuItem item) { // Do something when expanded return true; // Return true to expand action view } }; // Get the MenuItem for the action item MenuItem actionMenuItem = menu.findItem(R.id.myActionItem); // Assign the listener to that action item MenuItemCompat.setOnActionExpandListener(actionMenuItem, expandListener); // Any other things you have to do when creating the options menu... return true; }
アクション プロバイダの追加
アクション プロバイダを宣言するには、アクション ボタンの追加で説明しているように、ツールバーのメニュー リソースに <item>
要素を作成します。actionProviderClass
属性を追加し、アクション プロバイダ クラスの完全修飾クラス名に設定します。
たとえば次のコードは、アプリが他のアプリとデータを共有できるようにする、サポート ライブラリで定義されているウィジェットである ShareActionProvider
を宣言しています。
<item android:id="@+id/action_share" android:title="@string/share" app:showAsAction="ifRoom" app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
この場合、ShareActionProvider
が独自のグラフィックを提供するため、ウィジェットのアイコンを宣言する必要はありません。カスタム アクションを使用している場合は、アイコンを宣言します。
カスタム アクション プロバイダの作成については、ActionProvider
のリファレンスをご覧ください。ShareActionProvider
の構成については、そのクラスのリファレンスをご覧ください。