Overflow menus:アイテムをツールバーへ表示(showAsAction属性)

投稿日:  更新日:

Overflow menusはメニューのアイテムをツールバー(アクションバー)へ表示することが出来ます。

その方法を紹介します。

スポンサーリンク

showAsAction属性の指定

Overflow menusの実装」で紹介したサンプルのような、メニューを表示するだけの実装の場合、メニューのアイテムはオーバーフローアイコンに隠されます。

オーバーフローアイコンに隠された状態ではなく、メニューのアイテムをツールバー(アクションバー)へ表示させることが出来ます。

アイテムをツールバーへ表示させるためにshowAsAction属性を指定します。

【showAsAction属性なし】

showAsAction属性なし
【showAsAction属性あり】

showAsAction属性あり
スポンサーリンク

アイテムのタイトルを表示

showAsAction属性は3つのタイプがあり、それぞれの動作は次の通りです。

showAsActionアイテムの表示表示例
ifRoom配置が許される範囲へ表示
配置が許される個数を表示
上記から溢れるアイテムは隠される
アイテムのタイトルをifroomで表示
※すべてのアイテムがifRoom
【注意】
・アプリ名とアイテムが重なる時、アイテムの表示を優先する
always常に表示するアイテムのタイトルをalwaysで表示
※すべてのアイテムがalways
【注意】
・アプリ名とアイテムが重なる時、アイテムの表示を優先する
never、なし
(デフォルト)
常に表示しない
全てのアイテムが隠される
アイテムのタイトルをneverで表示
※すべてのアイテムがnever
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_file"
        android:title="File"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_edit"
        android:title="Edit"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_help"
        android:title="Help"
        app:showAsAction="ifRoom" />
</menu>
動的な実装の場合
class MainActivity : AppCompatActivity() {
    ...
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        //       groupID     itemID          order      title
        menu.add(Menu.FIRST, Menu.FIRST + 0, Menu.NONE, "File").apply {
            setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
        }
        menu.add(Menu.FIRST, Menu.FIRST + 1, Menu.NONE, "Edit").apply {
            setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
        }
        menu.add(Menu.FIRST, Menu.FIRST + 2, Menu.NONE, "Help").apply {
            setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
        }
        // ※orderが同じ(Menu.NONEは0)時はadd順に表示

        return true
    }
	...
}

表示できなかった(配置が許される範囲・個数から溢れた)アイテムはオーバーフローアイコンに隠されます。

スポンサーリンク

アイテムのアイコンを表示

icon属性へアイコン画像が指定されていると、タイトルよりもアイコンを優先して表示します。

showAsAction説明表示例
ifRoom配置が許される範囲へ表示
配置が許される個数を表示
上記から溢れるアイテムは隠される
アイテムのアイコンをifroomで表示
※すべてのアイテムがifRoom
【注意】
・アプリ名とアイテムが重なる時、アイテムの表示を優先する
always常に表示するアイテムのアイコンをalwaysで表示
※すべてのアイテムがalways
【注意】
・アプリ名とアイテムが重なる時、アイテムの表示を優先する
never、なし
(デフォルト)
常に表示しない
全てのアイテムが隠される
アイテムのアイコンをneverで表示
※すべてのアイテムがnever
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_file"
        android:icon="@drawable/outline_folder_24"
        android:title="File"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_edit"
        android:icon="@drawable/outline_edit_24"
        android:title="Edit"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_help"
        android:icon="@drawable/outline_help_outline_24"
        android:title="Help"
        app:showAsAction="ifRoom" />
</menu>
動的な実装の場合
class MainActivity : AppCompatActivity() {
    ...
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        //       groupID     itemID          order      title
        menu.add(Menu.FIRST, Menu.FIRST + 0, Menu.NONE, "File").apply {
            setIcon(R.drawable.outline_folder_24)
            setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
        }
        menu.add(Menu.FIRST, Menu.FIRST + 1, Menu.NONE, "Edit").apply {
            setIcon(R.drawable.outline_edit_24)
            setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
        }
        menu.add(Menu.FIRST, Menu.FIRST + 2, Menu.NONE, "Help").apply {
            setIcon(R.drawable.outline_help_outline_24)
            setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
        }
        // ※orderが同じ(Menu.NONEは0)時はadd順に表示

        return true
    }
	...
}

表示できなかった(配置が許される範囲・個数から溢れた)アイテムはオーバーフローアイコンに隠されます。

スポンサーリンク

アイテムのタイトル+アイコンを表示

アイテムのicon属性へアイコン画像が指定されていると、タイトルよりもアイコンを優先して表示します。

アイコンに加えてタイトルも表示したければ、アイテムのshowAsAction属性にwithTextを追加します。

showAsAction説明表示例
withTextアイコンと一緒にタイトルも表示する※単体の使用は不可
※ifRoom、alwaysと併用
ifRoom|withText配置が許される範囲へ表示
配置が許される個数を表示
上記から溢れるアイテムは隠される
【幅:320dpの時】
アイテムのタイトル+アイコンをifroomで表示
【幅:480dpの時】
アイテムのタイトル+アイコンをifroomで表示
※すべてのアイテムがifRoom|withText
【注意】
・画面の幅<480[dp]の時、アイテムのタイトルは表示されない
・アプリ名のタイトルとアイテムが重なる時、アイテムの表示を優先する
always|withText常に表示する【幅:320dpの時】
アイテムのタイトル+アイコンをalwaysで表示
【幅:480dpの時】
アイテムのタイトル+アイコンをalwaysで表示
※すべてのアイテムがalways|withText

【注意】
・画面の幅<480[dp]の時、アイテムのタイトルは表示されない
・アプリ名のタイトルとアイテムが重なる時、アイテムの表示を優先する
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_file"
        android:icon="@drawable/outline_folder_24"
        android:title="File"
        app:showAsAction="ifRoom|withText" />
    <item
        android:id="@+id/menu_edit"
        android:icon="@drawable/outline_edit_24"
        android:title="Edit"
        app:showAsAction="ifRoom|withText" />
    <item
        android:id="@+id/menu_view"
        android:icon="@drawable/outline_monitor_24"
        android:title="View"
        app:showAsAction="ifRoom|withText" />
    <item
        android:id="@+id/menu_search"
        android:icon="@drawable/outline_search_24"
        android:title="Search"
        app:showAsAction="ifRoom|withText" />
    <item
        android:id="@+id/menu_help"
        android:icon="@drawable/outline_help_outline_24"
        android:title="Help"
        app:showAsAction="ifRoom|withText" />
</menu>

表示できなかった(配置が許される範囲・個数から溢れた)アイテムはオーバーフローアイコンに隠されます。

「配置が許される範囲・個数」とは

ツールバー(アクションバー)の最も重要な役割はアプリ名を表示することがです。

メニューのアイテム(タイトル、アイコン)をツールバーに表示するとき、アプリ名の表示を妨げないように、アイテムの「配置が許される範囲・個数」が決められています。

この範囲・個数は、固定ではありません。画面の幅が広ければ大きくなるし、狭ければ小さくなります。これらの関係は次のように定義されています。

画面の大きさ[dp]許される個数
(アイコンを並べた幅[dp])
許される範囲
000≧画面の幅>6005(280)画面の幅/2
600≧画面の幅≧5004(224)
500>画面の幅≧3603(168)
360>画面の幅2(112)
※アイコンサイズ:56×56[dp]
public class ActionBarPolicy {
    ...
    /**
     * Returns the maximum number of action buttons that should be permitted within an action
     * bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit.
     * "always" items can override this.
     */
    public int getMaxActionButtons() {			// 許される個数
        final Configuration config = mContext.getResources().getConfiguration();
        final int width = config.screenWidthDp;
        final int height = config.screenHeightDp;
        final int smallest = config.smallestScreenWidthDp;
        if (smallest > 600 || (width > 960 && height > 720) || (width > 720 && height > 960)) {
            // For values-w600dp, values-sw600dp and values-xlarge.
            return 5;
        } else if (width >= 500 || (width > 640 && height > 480) || (width > 480 && height > 640)) {
            // For values-w500dp and values-large.
            return 4;
        } else if (width >= 360) {
            // For values-w360dp.
            return 3;
        } else {
            return 2;
        }
    }
	...
    public int getEmbeddedMenuWidthLimit() {	// 許される範囲
        return mContext.getResources().getDisplayMetrics().widthPixels / 2;
    }
	...
}

ちなみに、記事中のツールバーのスナップショットはスクリーンサイズ320×480[px](mdpi)の端末です。
※mdpiの端末は1[px]=1[dp]です。

スポンサーリンク

関連記事:

Material Design ComponentsにMenusというカテゴリがあります。 「Menus(メニュー)」なので、言葉のとおり、選択する項目を一覧表示する機能です。 Menusはメニューの表現方法によって、幾つかの種類があります。 このMenusの種類と特徴を紹介します。 ...
Overflow menusの実装方法を紹介します。 ...
ツールバー(アクションバー)へActionViewを表示させる方法を紹介します。 ...
ツールバー(アクションバー)へActionLayoutを表示させる方法を紹介します。 ...
スポンサーリンク