LoginSignup
6
6

More than 5 years have passed since last update.

support.v4のActionProviderを使ってActionBarにサブメニューを追加したい

Last updated at Posted at 2014-06-30

サブメニューが表示されなかったりしてハマったのでメモ。

Activityの書き方

YourActivity.java
public class YourActivity extends ActionBarActivity {

    /* hogehoge */

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        MenuItemCompat.setActionProvider(menu.findItem(R.id.awesome_item), new YourActionProvider(this));
        return super.onCreateOptionsMenu(menu);
    }

    /* hogehoge */
}

ActivityのonCreateOptionsMenuでメニューアイテムの初期化を行う。
MenuItemCompatを使って指定したアイテムにActionProviderを割り当てます。

menuのXMLファイルの書き方

次にR.menu.mainの内容をみてみます

main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
    <item
        android:id="@+id/awesome_item"
        android:icon="@android:drawable/ic_menu_camera"
        app:showAsAction="ifRoom"
        android:title="@android:string/cancel"
        app:actionProviderClass="com.stenpel.awesome.app.common.CameraActionProvider" />
</menu>

menuの中にitemがひとつだけあります。
YourActivityでActionProviderを割り当てられている、R.id.awesome_itemですね。
showAsAction,actionProviderClassはandroidではなく独自に定義したappを指定します。appの部分は好きな文字列でOKです。

独自拡張したActionProviderの書き方

次は独自のActionProviderを書きます

YourActionProvider.java
public class CameraActionProvider extends android.support.v4.view.ActionProvider {

    /**
     * Creates a new instance.
     *
     * @param context Context for accessing resources.
     */
    public CameraActionProvider(Context context) {
        super(context);
    }

    @Override
    public View onCreateActionView() {
        return null;
    }

    @Override
    public boolean hasSubMenu() {
        return true;
    }

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        subMenu.clear();
        MenuInflater inflater = new MenuInflater(getContext());
        inflater.inflate(R.menu.awesome_provider_menu, subMenu);
    }
}

ActionProviderでは表示したいサブメニューを初期化を担当します。
初期化するメソッドがonPrepareSubMenuです。
この中でR.menu.awesome_provider_menuというxmlを実体化しています。
ちなみに、このonPrepareSubMenuはMenuItemが選択されるたびに呼び出されるためsubMenu.clear()でサブメニューを一旦すべて消しています。これをやっておかないとMenuItemを選択されるたびにサブメニューアイテムが重複して追加されていってしまいます。

サブメニューのXMLファイルの書き方

最後に、サブメニュー一覧用のXMLを書きます。

awesom_provider_menu.xml
<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/awesome_provider_sub_menu_1"
        android:title="@string/awesome_text_1"
        android:icon="@android:drawable/ic_menu_camera" />
    <item
        android:id="@+id/awesome_provider_sub_menu_2"
        android:title="@string/awesome_text_2"
        android:icon="@android:drawable/ic_menu_compass" />
</menu>

ここは特に変わったところはない感じです。menuとitemを入れ子にして定義すればOKです。

動いてよかった。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6