アプリにダイナミック カラーを追加する

1. 始める前に

この Codelab では、スターター アプリであるチップ計算アプリを更新して、マテリアル デザイン 3 の新機能を使用できるようにします。これにより、ユーザーの壁紙に基づいてアプリのユーザー インターフェースを動的にテーマ設定できるようになります。以下に、ダイナミック カラーを適用したアプリのスクリーンショットをいくつか示します。また、色の適用方法を制御できる追加のシナリオについても説明します。

前提条件

デベロッパーは

  • Android の基本的なテーマ設定のコンセプトを理解している
  • アプリのテーマの変更に慣れている

学習内容

  • 既存のマテリアル コンポーネントとマテリアル 3 のテーマを区別する方法
  • テーマを Material 3 に更新する方法
  • ツールを使用してテーマを作成し、適用する方法
  • テーマ属性の相互関係

必要なもの

2. スターター アプリの概要

Tip Time アプリは、チップをカスタマイズするオプションを含むチップ計算アプリです。これは、Kotlin を用いた Android の基本トレーニング コースのサンプルアプリの 1 つです。

59906a9f19d6b804.png

3. Gradle 依存関係の更新

実際のテーマを更新してダイナミック カラーを適用する前に、アプリの build.gradle ファイルにいくつかの変更を加える必要があります。

dependencies セクションで、マテリアル ライブラリが 1.5.0-alpha04 以降であることを確認します。

dependencies {
    // ...
    implementation 'com.google.android.material:material:<version>'
}

android セクションで、compileSdkVersion と targetSdkVersion を変更します。

31 以降:

android {
    compileSdkVersion 31
    // ...

    defaultConfig {
        // ...
        targetSdkVersion 31
    }
}

この手順は、比較的最近の依存関係を持つアプリを前提としています。マテリアルまたはそれより古いバージョンをまだ使用していないアプリの場合は、Android 向けマテリアル デザイン コンポーネントスタートガイドのドキュメントの手順をご確認ください。

テーマを作成した場所で、Theme.MaterialComponents.* の参照を Theme.Material3.* に変更します。一部のスタイルは Material3 名前空間に新しいスタイルがまだありませんが、親テーマが Theme.Material3.* に更新されると、ほとんどのコンポーネントは新しいスタイルを継承します。下の画像では、ボタンが新しい丸みを帯びたテーマになっていることがわかります。

以下のテーマファイルでは、親テーマのみが変更されています。このテーマはまもなく完全に置き換えられます。一部のカラー属性は非推奨となり、作成したカスタム スタイルの一部は Material3 で標準になりましたが、

themes.xml

<style name="Theme.TipTime" parent="Theme.Material3.Light">
   <!-- Primary brand color. -->
   <item name="colorPrimary">@color/green</item>
   <item name="colorPrimaryVariant">@color/green_dark</item>
   <item name="colorOnPrimary">@color/white</item>
   <!-- Secondary brand color. -->
   <item name="colorSecondary">@color/blue</item>
   <item name="colorSecondaryVariant">@color/blue_dark</item>
   <item name="colorOnSecondary">@color/black</item>
   <!-- Status bar color. -->
   <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
   <!-- For text input fields -->
   <item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
   <!-- For radio buttons -->
   <item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
   <!-- For switches -->
   <item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>

f91e2acbac7cd469.png

4. カラー テーマとカラーロールについて

Material 3 のカラーシステムは、組織的なアプローチで UI に色を適用します。Theme.AppCompat の多くの属性は引き続き使用されています。ただし、Theme.MaterialComponents.* で属性が追加され、Theme.Material3.* でさらに追加されたため、アプリのすべての画面を調べて、実装されていないプロパティがベーステーマから漏れていないことを確認することが重要です。

カラーロールについて

マテリアル 3 テーマには、色に関連する属性が 20 個以上あります。最初は難しく思えるかもしれませんが、実際には、同じ 4 ~ 5 色のロールと組み合わせて派生色を作成するキーカラーは数種類しかありません。

これらのカラーグループは次のとおりです。

  • Primary: アプリのプライマリ カラー
  • セカンダリ: アプリのセカンダリ カラー
  • ターシャリ: プライマリとセカンダリの補色である 3 番目の色
  • エラー。エラー テキストとダイアログに使用されます
  • 背景
  • Surface、SurfaceVariant、Surface Inverse

プライマリ、セカンダリ、ターシャリ、エラーのロールは次のとおりです。

<ベースカラー>

ベースカラー

on<ベースカラー>

ベースカラーの上に表示されるアイコンとテキストの色

<ベースカラー>コンテナ

ベースカラーから派生した色。ボタンやダイアログなどに使用されます。

on<ベースカラー>Container

コンテナのアイコンとテキストの色

たとえば、マテリアル 3 のデフォルトのスタイル設定のフローティング アクション ボタンは、ベースカラーとして Primary を使用するため、ボタンの背景色には primaryContainer を、コンテンツには onPrimaryContainer を使用します。

テーマを手動でカスタマイズする場合は、変更するすべての基本色の on<base color> 属性が判読可能であることを最低限確認する必要があります。

ベースからアプリまでアーティファクトがないようにするには、カラーグループ内のすべてのロールを同時に調整することをおすすめします。

背景とサーフェスのベースカラーには、通常、ベースカラー自体と、その上に表示されるアイコンやテキストの on<base color> の 2 つの役割があります。

5. Material Theme Builder を使用してマテリアル 3 のテーマを作成する

マテリアル テーマビルダーを使用すると、カスタム カラーパターンを簡単に作成し、組み込みのコード エクスポートを使用して M3 カラーシステムに移行し、ダイナミック カラーを活用できます。詳しくは、material.io/material-theme-builder をご覧ください。

Tip Time アプリのテーマにはコンポーネントのスタイルがいくつか含まれていますが、ほとんどのスタイルは Material 3 テーマのデフォルトです。注意すべきキーカラーは、プライマリとセカンダリの 2 つだけです。

これらは、緑のプライマリ カラー(#1B5E20)と青のセカンダリ カラー(#0288D1)に対応しています。

これらの色をマテリアル テーマビルダーに入力して、完全なテーマをエクスポートできます(完全な概要へのリンクが別途あることを前提としています)。

入力した色は、色生成アルゴリズムに合わせて色調が変化し、補色と判読可能な色が確保される場合があります。

以下は、カスタムカラーを入力したときに生成される値のサブセットです。

7f6c5a33f5233811.png

6. マテリアル テーマ ビルダーのエクスポート ファイルの操作

エクスポート アーカイブには、ライトモードとダークモードに対応する独自の themes.xml ファイルを含む values/ ディレクトリと values-night/ ディレクトリが含まれています。すべての色は values/colors.xml で定義されています。

f66a64db2989a260.png

ファイルはそのままコピーできますが、テーマ名が一致するように AndroidManifest.xml またはテーマ ファイルで変更する必要があります。ツールからのデフォルト名は AppTheme です。

アプリを再起動すると、ほぼ同じように表示されます。特に注目すべき変更は、Switch と RadioButton です。選択状態がプライマリ カラーのトーンとセカンダリ カラーでテーマ設定されるようになりました。大規模なアプリケーションでは、一部の設計を見直す必要がある場合があります。

38a50ada47fd5ea4.png

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.tiptime">

   <application ...>
       <activity android:name=".MainActivity"
           android:exported="true">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>

</manifest>

7. ダイナミック カラーを追加する

マテリアル 3 の適切なテーマを使用すれば、少しの追加で UI を動的にできます。

ダイナミック カラー API を使用すると、すべてのアクティビティにダイナミック カラーを適用できます。

アプリ、個々のアクティビティ、個々のビューまたはフラグメントに適用できます。対象

このアプリでは、ダイナミック カラーをグローバルに適用します。

Application クラス ファイルを作成する

class TipTimeApplication: Application() {
    override fun onCreate() {
        // Apply dynamic color
        DynamicColors.applyToActivitiesIfAvailable(this)
    }
}

この新しく作成したファイルを Android マニフェストで参照する必要があります。

AndroidManifest.xml

< application android name=".TipTimeApplication
<!--- Other existing attributes –>

</application >

Android 12 以降のシステムでは、デフォルト スキームのユーザーの壁紙が調べられ、複数のトーンパレットが生成されます。これらのパレットの値は、ThemeOverlay の作成に使用されます。

DynamicColors クラスは、ActivityPreCreated でインターセプトして、システムが作成したダイナミック テーマ オーバーレイまたはユーザーが指定したオーバーレイを適用する ActivityLifecycleCallbacks を登録します。

eba71f96f4ba9cdf.png

8. カスタムテーマ オーバーレイの適用

Google のツールではテーマ オーバーレイをエクスポートできますが、少数の属性をオーバーライドする場合は手動で作成することもできます。

テーマ オーバーレイは別のテーマと組み合わせて使用することを想定しており、ベーステーマの上に変更される値のみを提供します。

たとえば、ブランディングなどの理由で、メインカラーのトーンを赤のシェードにする必要があるとします。次のファイルと属性を使用して、それを行うことができます。

colors.xml

<resources>
    <color name="overlay_light_primary">#9C4146</color>
    <color name="overlay_light_onPrimary">#FFFFFF</color> 
    <color name= "overlay_light_primaryContainer">#FFDADB</color>
    <color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >

themes_overlays.xml

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
    <item name="colorPrimary">@color/overlay_light_primary</item>
    <item name="colorOnPrimary">@color/overlay_light_onPrimary</item> 
    <item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item> 
    <item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>

上記のコードの場合、Android 12 は動的ライトテーマを適用し、その上に変更をオーバーレイします。または、次のいずれかを含む任意の有効な ThemeOverlay を親として使用することもできます。

ThemeOverlay.Material3.Light

ThemeOverlay.Material3.Dark

ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark

ThemeOverlay.Material3.DynamicColors.DayNight

マテリアルのデフォルトの代わりにこのテーマ オーバーレイを使用するには、DynamicColors.applyToActivitiesIfAvailable の呼び出しを次のように変更します。

DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

d87020776782036f.png

9. カスタム属性にダイナミック カラーを追加する

これまでは、Material 3 テーマにすでに存在するプロパティをオーバーライドしてきました。ダイナミック カラーでは、割り当てる必要のあるカスタム属性が 1 つ以上ある場合もあります。

アプリがダイナミック カラーを有効にすると、5 つの色調パレット(3 つのアクセント パレットと 2 つのニュートラル パレット)にアクセスできるようになります。これらのパレットには、おおよそ次のような役割があります。

system_accent1

メインカラーのトーン

system_accent2

セカンダリ カラーのトーン

system_accent3

ターシャリ カラーのトーン

system_neutral1

ニュートラルな背景とサーフェス

system_neutral2

ニュートラルなサーフェスとアウトライン

各パレットには、白から黒までのさまざまな色調のステップがあります。

黒: 0、10、50、100、200、300、400、500、600、700、800、900、1000。

ダイナミック カラーの UI を設計する際は、特定の色について考えるのではなく、そのコンポーネントの色調と輝度がデザイン システム内の他のコンポーネントとどのような関係にあるかを考える必要があります。

たとえば、セカンダリ アクセント パレットを使用してアイコンをテーマ設定したいとします。attrs.xml に次のエントリを追加して、アイコンをティントする属性を追加しました。

attrs.xml

<resources>
    <attr name="iconColor" format="color" />
</resources>

テーマ オーバーレイは次のようになります。

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight"> 
<item name="iconColor">@android:color/system_accent2_600</item>
</style>

アプリを再インストールして壁紙を変更すると、アプリはそのセカンダリ パレットを取得します。

11ef0035702640d9.png

264b2c2e74c5f574.png

これらのパレットは Android 12(API 31)に固有のものであるため、アプリの最小 SDK が 31 以上に設定されていない限り、関連するファイルを -v31 接尾辞の付いたフォルダに配置する必要があります。

10. まとめ

この Codelab では、次のことを行いました。

  • 依存関係を追加して、テーマを Material 3 にアップグレードします。
  • 新しいカラーグループとロールについて理解します。
  • 静的テーマからダイナミック カラーに移行する方法を理解する。
  • テーマ オーバーレイの使用方法と、カスタム テーマ属性にダイナミック カラーを使用する方法を理解する。