それがいいことの序章です

楽しいことならいっぱい夢見ることならめいっぱい

Toolbarを使うときのtheme設定

Toolbarにメニューを表示するとよく引っかかるのがアイコンの色の定義。
特に、独自で設定したメニューアイコンと、オーバーフローメニューのアイコンの色がうまく合わないというパターン。
今回はここを解決するひとつの方法をメモ。

前提

  • MDC Library ver1.2.0-alpha05

実装

Toolbar用のThemeOverlayに以下の2つが用意されていた

  • ThemeOverlay.MaterialComponents.Toolbar.Primary
  • ThemeOverlay.MaterialComponents.Toolbar.Surface
<style name="ThemeOverlay.MaterialComponents.Toolbar.Primary" parent="">
  <item name="colorControlNormal">?attr/colorOnPrimary</item>
  <item name="actionMenuTextColor">?attr/colorOnPrimary</item>
</style>
<style name="ThemeOverlay.MaterialComponents.Toolbar.Surface" parent="">
  <item name="colorControlNormal">@color/material_on_surface_emphasis_medium</item>
  <item name="actionMenuTextColor">@color/material_on_surface_emphasis_medium</item>
</style>

@color/material_on_surface_emphasis_mediumは、colorOnSurfaceの60%透過色です。

これをToolbarのテーマに適用させると楽そう。(Toolbar単体で使うとき)

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:theme="@style/ThemeOverlay.MaterialComponents.Toolbar.Primary" />

あるいは、各プロジェクトのテーマに応じて独自のThemeOverlayを作るのも良さそう

<!-- アイコンカラーをPrimarySurfaceに -->
<style name="ThemeOverlay.AppName.Toolbar.PrimarySurface" parent="">
  <item name="colorControlNormal">?attr/colorOnPrimarySurface</item>
  <item name="actionMenuTextColor">?attr/colorOnPrimarySurface</item>
</style>

さらに、ToolbarのアイコンカラーはcolorControlNormalで決まるので、 アイコン側にも?attr/colorControlNormalのtintをかけるといい感じになりそう。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:tint="?attr/colorControlNormal"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#FF000000"
        android:pathData="M17.6,11.48 ..." />
</vector>

他のやり方

いい感じにしたくてthemeを漁ったりしてみてやったぜって言ってたけど、menuのアイコンカラーを変えるだけならapp:iconTintを使ってmenuファイル側でできるのであった…

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >

    <item
        android:id="@+id/menu_id"
        android:icon="@drawable/ic_android"
        android:title="@string/menu_label"
        app:iconTint="?attr/colorOnPrimarySurface"
        app:showAsAction="always"
        />

</menu>