47
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

ActionBarにメニューの「・・・」を常時表示してサブメニューにアイコンを表示する

背景

qiita1.png

ActionBarSherlock や Support Library の ActionBarActivity を使えば Android 2.x でも ActionBar 付きの Activity を作れるわけですが、物理メニューキーがある端末ではActionBarに「・・・」(いわゆるthree dots)が表示されません。

Androidのデザインガイドライン的にはこれが正しい振る舞いと思いますし個人的にはそれでかまわないんですが、サポートの手間がものすごくかかる(「もし画面右上に「・・・」ボタンがあればそれを押し、なければ端末のメニューボタンを押して」を毎回説明する)ので常時表示することができればウレシイなと思って調べてみました。

ついでに上記スクリーンショットのように、サブメニューにアイコンを付けられるようになったのでメニュー項目が若干分かりやすくなるというメリットもあります。

余談ですが、「端末のメニューボタンを押してください」とユーザーに伝えたら「メニューボタンって何ですか?」って質問される場合もありました。以下はそんな世界にだけ通用するフィクションみたいなものだと思って頂ければ。。

実現方法

showAsAction="always" のic_action_overflowのボタンを表示して、そのサブメニューとしてメニュー項目を作成します。

res/menu/main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:yourapp="http://schemas.android.com/apk/res-auto" >

    <!-- トップページ -->
    <item
        android:id="@+id/menu_toppage"
        android:icon="@drawable/icon32_ic_menu_home"
        android:title="トップページ"
        yourapp:showAsAction="always"/>

    <!-- 共有 -->
    <item
        android:id="@+id/menu_share"
        android:icon="@drawable/icon32_dummy_space"
        android:title="共有"
        yourapp:showAsAction="always"/>

    <!-- Options -->
    <item
        android:id="@+id/overflow_options"
        android:icon="@drawable/ic_action_overflow_dark"
        android:title="Menu"
        yourapp:showAsAction="always">
        <menu>

            <!-- ブラウザで開く -->
            <item
                android:id="@+id/menu_share_by_browser"
                android:icon="@drawable/icon32_dummy_space"
                android:title="ブラウザで開く"
                yourapp:showAsAction="never"/>

            <!-- URLの確認 -->
            <item
                android:id="@+id/menu_show_url"
                android:icon="@drawable/icon32_dummy_space"
                android:title="URLの確認"
                yourapp:showAsAction="never"/>

            <!-- ページ内検索 -->
            <item
                android:id="@+id/menu_text_find_start"
                android:icon="@drawable/icon32_dummy_space"
                android:title="ページ内検索"
                yourapp:showAsAction="never"/>
...
        </menu>
    </item>

</menu>

※日本人向けのアプリなのでandroid:title属性に直接書いちゃってるけど当然文字列リソースを用意すべきですよ。

※android:icon属性を@drawable/icon32_dummy_spaceにしているのは実行時に onPrepareOptionsMenu で IconicDroidのアイコンに差し替えるためです。

MainActivity.java
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        final MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);

        mainMenu = menu;

        return super.onCreateOptionsMenu(menu);
    }

詳細は stackoverflowのこの回答 を参照してください。ic_action_overflow などのリソースもリンク先にあります。

メニューボタン押下時のサブメニュー表示

上記だけだと物理メニューキーを押してもサブメニューは出てくれないのでそこも自力でハンドリングしてあげます。

    private Menu mainMenu;
...
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        final MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);

        mainMenu = menu;

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
...
        final int action = event.getAction();
        final int keyCode = event.getKeyCode();
        if (action == KeyEvent.ACTION_UP) {
            // メニュー表示
            if (keyCode == KeyEvent.KEYCODE_MENU) {
                if (mainMenu != null) {
                    mainMenu.performIdentifierAction(R.id.overflow_options, 0);
                }
                return true;
            }
        }
...
    }

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
47
Help us understand the problem. What are the problem?