Compose のマテリアル デザイン 3

Jetpack Compose には、マテリアル デザインの進化版である Material You と Material 3 Expressive の実装が用意されています。M3 Expressive は、マテリアル デザイン 3 を拡張したもので、テーマ設定、コンポーネント、モーション、タイポグラフィなどに関する調査に基づいたアップデートが含まれています。これらはすべて、ユーザーが気に入るような魅力的で望ましいプロダクトを作成できるように設計されています。ダイナミック カラーなどの Material You のパーソナライズ機能もサポートしています。M3 Expressive は、Android 16 の視覚的スタイルとシステム UI を補完します。

以下では、Reply サンプルアプリを例として、マテリアル デザイン 3 の実装方法を示します。Reply サンプルは、完全にマテリアル デザイン 3 に基づいています。

マテリアル デザイン 3 を使用した Reply サンプルアプリ
図 1。マテリアル デザイン 3 を使用した Reply サンプルアプリ

依存関係

Compose アプリでマテリアル 3 の使用を開始するには、Compose マテリアル 3 依存関係を build.gradle ファイルに追加します。

implementation "androidx.compose.material3:material3:$material3_version"

依存関係を追加したら、色、タイポグラフィ、シェイプなどのマテリアル デザイン システムをアプリに追加できます。

試験運用版 API

一部の M3 API は試験運用版とみなされています。その場合は、ExperimentalMaterial3Api アノテーションを使用して、関数レベルまたはファイルレベルでオプトインする必要があります。

// import androidx.compose.material3.ExperimentalMaterial3Api
@Composable
fun AppComposable() {
    // M3 composables
}

マテリアル テーマ設定

M3 テーマには、カラーパターンタイポグラフィシェイプのサブシステムが含まれています。これらの値をカスタマイズすると、その変更は、アプリをビルドする際に使用する M3 コンポーネントに自動的に反映されます。

マテリアル デザインのサブシステム: 色、タイポグラフィ、シェイプ
図 2. マテリアル デザインのサブシステム: 色、タイポグラフィ、シェイプ

Jetpack Compose は、M3 MaterialTheme コンポーザブルを使用して、これらのコンセプトを実装します。

MaterialTheme(
    colorScheme = /* ...
    typography = /* ...
    shapes = /* ...
) {
    // M3 app content
}

アプリのコンテンツをテーマ設定するには、アプリ固有のカラーパターン、タイポグラフィ、シェイプを定義します。

カラーパターン

カラーパターンの基盤は、5 つの主要なカラーのセットです。これらの各色は、マテリアル 3 コンポーネントで使用される 13 トーンのトーンパレットに関連しています。たとえば、返信のライトモードの配色を次に示します。

Reply サンプルアプリのライト カラーパターン
図 3. Reply サンプルアプリのライト カラーパターン

詳しくは、カラーパターンとカラーロールをご覧ください。

カラーパターンを生成する

カスタムの ColorScheme は手動で作成できますが、多くの場合、ブランドのソースカラーを使用して生成するほうが簡単です。マテリアル テーマビルダー ツールを使用すると、この処理を行い、必要に応じて Compose テーマ設定コードをエクスポートできます。次のファイルが生成されます。

  • Color.kt には、ライトモードとダークモードの色に対して定義されたすべてのロールを含むテーマの色が含まれます。

val md_theme_light_primary = Color(0xFF476810)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFFC7F089)
// ..
// ..

val md_theme_dark_primary = Color(0xFFACD370)
val md_theme_dark_onPrimary = Color(0xFF213600)
val md_theme_dark_primaryContainer = Color(0xFF324F00)
// ..
// ..

  • Theme.kt には、ライトとダークのカラーパターンとアプリのテーマの設定が含まれます。

private val LightColorScheme = lightColorScheme(
    primary = md_theme_light_primary,
    onPrimary = md_theme_light_onPrimary,
    primaryContainer = md_theme_light_primaryContainer,
    // ..
)
private val DarkColorScheme = darkColorScheme(
    primary = md_theme_dark_primary,
    onPrimary = md_theme_dark_onPrimary,
    primaryContainer = md_theme_dark_primaryContainer,
    // ..
)

@Composable
fun ReplyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colorScheme =
        if (!darkTheme) {
            LightColorScheme
        } else {
            DarkColorScheme
        }
    MaterialTheme(
        colorScheme = colorScheme,
        content = content
    )
}

ライトモードとダークモードをサポートするには、isSystemInDarkTheme() を使用します。システム設定に基づいて、使用するカラーパターン(ライトまたはダーク)を定義します。

動的なカラーパターン

ダイナミック カラーは Material You の重要な要素です。アルゴリズムはそれによってユーザーの壁紙からカスタムカラーを導出し、それらがアプリとシステム UI に適用されるようにします。このカラーパレットは、ライト カラーパターンとダーク カラーパターンを生成するための出発点として使用されます。

壁紙からの動的テーマ設定(左)とデフォルトのアプリのテーマ設定(右)の Reply サンプルアプリ
図 4. 壁紙からの動的テーマ設定(左)とデフォルトのアプリのテーマ設定(右)の Reply サンプルアプリ

ダイナミック カラーは Android 12 以降で使用できます。ダイナミック カラーを使用できる場合は、動的な ColorScheme を設定できます。使用できない場合は、代わりにカスタムのライトまたはダーク ColorScheme を使用してください。

ColorScheme には、動的なライト カラーパターンまたはダーク カラーパターンを作成するためのビルダー関数が用意されています。

// Dynamic color is available on Android 12+
val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colors = when {
    dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current)
    dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
    darkTheme -> DarkColorScheme
    else -> LightColorScheme
}

色の使い方

アプリでマテリアル テーマの色にアクセスするには、MaterialTheme.colorScheme を使用します。

Text(
    text = "Hello theming",
    color = MaterialTheme.colorScheme.primary
)

各カラーロールは、コンポーネントの状態、視認性の高さ、強調に応じて、さまざまな場所で使用できます。

  • プライマリはベースカラーです。視認性の高いボタン、アクティブ状態、浮き上がったサーフェスの色合いなどの主要コンポーネントに使用されます。
  • セカンダリ キーカラーは、UI の視認性の低いコンポーネント(フィルタラベルなど)に使用され、色の表現の幅を広げます。
  • ターシャリ キーカラーは、プライマリ カラーとセカンダリ カラーのバランスを保つため、または要素に注意を引くための、対照的なアクセントのロールを導き出すために使用されます。

Reply サンプルアプリのデザインでは、プライマリ コンテナの上にオン プライマリ コンテナの色を使用して、選択した項目を強調しています。

プライマリ コンテナと、on-primary-container カラーのテキスト フィールド。
図 5. プライマリ コンテナと、on-primary-container 色のテキスト フィールド。

Card(
    colors = CardDefaults.cardColors(
        containerColor =
        if (isSelected) MaterialTheme.colorScheme.primaryContainer
        else
            MaterialTheme.colorScheme.surfaceVariant
    )
) {
    Text(
        text = "Dinner club",
        style = MaterialTheme.typography.bodyLarge,
        color =
        if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer
        else MaterialTheme.colorScheme.onSurface,
    )
}

返信ナビゲーション ドロワーでは、セカンダリ コンテナとターシャリ コンテナの色がコントラストとして使用され、強調とアクセントが作成されています。

フローティング アクション ボタンの tertiary-container と on-tertiary-container の組み合わせ。
図 6. フローティング アクション ボタンの tertiary-container と on-tertiary-container の組み合わせ。

タイポグラフィ

マテリアル デザイン 3 では、マテリアル デザイン 2 から進化したテキスト スタイルなどのタイプスケールが定義されています。名前とグループ化は、表示、見出し、タイトル、本文、ラベルに簡略化され、それぞれに大、中、小のサイズがあります。

マテリアル デザイン 3 のデフォルトのタイポグラフィ スケール
図 7. マテリアル デザイン 3 のデフォルトのタイポグラフィ スケール
M3 デフォルトのフォントサイズ/行の高さ
displayLarge Roboto 57/64
displayMedium Roboto 45/52
displaySmall Roboto 36/44
headlineLarge Roboto 32/40
headlineMedium Roboto 28/36
headlineSmall Roboto 24/32
titleLarge New- Roboto Medium 22/28
titleMedium Roboto Medium 16/24
titleSmall Roboto Medium 14/20
bodyLarge Roboto 16/24
bodyMedium Roboto 14/20
bodySmall Roboto 12/16
labelLarge Roboto Medium 14/20
labelMedium Roboto Medium 12/16
labelSmall New Roboto Medium, 11/16

タイポグラフィを定義する

Compose には、既存の TextStyle クラスおよびフォント関連のクラスとともに、マテリアル 3 タイプスケールをモデル化するための M3 Typography クラスが用意されています。Typography コンストラクタは各スタイルのデフォルトを提供するため、カスタマイズしないパラメータは省略できます。

val replyTypography = Typography(
    titleLarge = TextStyle(
        fontWeight = FontWeight.SemiBold,
        fontSize = 22.sp,
        lineHeight = 28.sp,
        letterSpacing = 0.sp
    ),
    titleMedium = TextStyle(
        fontWeight = FontWeight.SemiBold,
        fontSize = 16.sp,
        lineHeight = 24.sp,
        letterSpacing = 0.15.sp
    ),
    // ..
)
// ..

さまざまなタイポグラフィの使用方法に対応する body large、body medium、label medium。
図 8. さまざまなタイポグラフィの使用に対応する body large、body medium、label medium。

マテリアル デザイン タイプのスケールの 15 個のデフォルト スタイルがすべて、プロダクトで必要になるとは限りません。この例では、縮小されたセットに対して 5 つのサイズが選択され、残りは省略されています。

TextStylefontFamilyletterSpacing などのフォント関連プロパティのデフォルト値を変更することで、タイポグラフィをカスタマイズできます。

bodyLarge = TextStyle(
    fontWeight = FontWeight.Normal,
    fontFamily = FontFamily.SansSerif,
    fontStyle = FontStyle.Italic,
    fontSize = 16.sp,
    lineHeight = 24.sp,
    letterSpacing = 0.15.sp,
    baselineShift = BaselineShift.Subscript
),

Typography を定義したら、それを M3 MaterialTheme に渡します。

MaterialTheme(
    typography = replyTypography,
) {
    // M3 app Content
}

テキスト スタイルを使用する

MaterialTheme.typography を使用すると、M3 MaterialTheme コンポーザブルに渡されるタイポグラフィを取得できます。

Text(
    text = "Hello M3 theming",
    style = MaterialTheme.typography.titleLarge
)
Text(
    text = "you are learning typography",
    style = MaterialTheme.typography.bodyMedium
)

マテリアル ガイドラインについて詳しくは、タイポグラフィの適用をご覧ください。

シェイプ

マテリアル サーフェスはさまざまな形状で表示できます。シェイプはユーザーの注意を引き、コンポーネントを明確に示し、状態を伝え、ブランドを表現するために役立ちます。

形状スケールはコンテナの角のスタイルを定義し、正方形から完全な円形まで、さまざまな丸みを提供します。

図形を定義する

Compose には、新しい M3 シェイプをサポートするための拡張パラメータを備えた M3 Shapes クラスがあります。M3 のシェイプ スケールは、タイプスケールに似ており、UI 全体でシェイプの表現範囲を実現します。

シェイプにはさまざまなサイズがあります。

  • XS
  • XL

デフォルトでは、各シェイプにデフォルト値がありますが、オーバーライドできます。

val replyShapes = Shapes(
    extraSmall = RoundedCornerShape(4.dp),
    small = RoundedCornerShape(8.dp),
    medium = RoundedCornerShape(12.dp),
    large = RoundedCornerShape(16.dp),
    extraLarge = RoundedCornerShape(24.dp)
)

Shapes を定義したら、それを M3 MaterialTheme に渡すことができます。

MaterialTheme(
    shapes = replyShapes,
) {
    // M3 app Content
}

シェイプを使用する

MaterialTheme で、すべてのコンポーネントのシェイプ スケールをカスタマイズすることも、コンポーネントごとにカスタマイズすることもできます。

デフォルト値で中サイズと大サイズのシェイプを適用します。

Card(shape = MaterialTheme.shapes.medium) { /* card content */ }
FloatingActionButton(
    shape = MaterialTheme.shapes.large,
    onClick = {
    }
) {
    /* fab content */
}

Reply サンプルアプリのカードの Medium シェイプとフローティング アクション ボタンの Large シェイプ。
図 9. Reply サンプルアプリのカードの Medium シェイプとフローティング アクション ボタンの Large シェイプ

他には、Compose の一部である RectangleShapeCircleShape という 2 つのシェイプがあります。長方形は枠線の半径がなく、円の輪郭は完全な丸いエッジを示しています。

Card(shape = RectangleShape) { /* card content */ }
Card(shape = CircleShape) { /* card content */ }

次の例は、デフォルトのシェイプ値が適用されたコンポーネントの一部を示しています。

すべてのマテリアル 3 コンポーネントのデフォルトのシェイプ値。
図 10. すべてのマテリアル 3 コンポーネントのデフォルトのシェイプ値。

マテリアル ガイドラインについて詳しくは、シェイプの適用をご覧ください。

強調点

M3 での強調は、さまざまなバリエーションの色と、on-color の組み合わせを使用して提供されます。M3 では、UI を強調する方法が 2 つあります。

  • 拡張 M3 カラーシステムの on-surface および on-surface-variants の色に加えて、サーフェス、surface-variant、背景を使用します。たとえば、サーフェスは、on-surface-variant とともに使用できます。また、surface-variant を on-surface と併用すると、異なる強調レベルを指定できます。
強調に無彩色の組み合わせを使用する。
図 11. 強調にニュートラルな色の組み合わせを使用する。
  • テキストでは異なるフォントの太さを使用する。前述のように、タイプスケールにカスタム ウェイトを設定して、異なる強調を指定できます。

bodyLarge = TextStyle(
    fontWeight = FontWeight.Bold
),
bodyMedium = TextStyle(
    fontWeight = FontWeight.Normal
)

高度

マテリアル 3 では、主に色調カラー オーバーレイを使用してエレベーションを表現します。これは、コンテナとサーフェスを区別する新しい方法です。色調エレベーションを高くすると、シャドウに加えて、より目立つ色調が使用されます。

シャドウ エレベーションを含む色調エレベーション
図 12. シャドウ エレベーションを含む色調エレベーション E

ダークテーマのエレベーション オーバーレイも、マテリアル 3 の色調カラー オーバーレイに変更されました。オーバーレイの色は、プライマリ カラースロットで指定されます。

マテリアル デザイン 3 のシャドウ エレベーションと色調エレベーション
図 13. マテリアル デザイン 3 のシャドウ エレベーションと色調エレベーション

M3 Surface(ほとんどの M3 コンポーネントの背後にあるバッキング コンポーザブル)は、色調エレベーションとシャドウ エレベーションの両方をサポートします。

Surface(
    modifier = Modifier,
    tonalElevation = /*...
    shadowElevation = /*...
) {
    Column(content = content)
}

マテリアル コンポーネント

マテリアル デザインには、マテリアル コンポーネント(ボタン、チップ、カード、ナビゲーション バーなど)の豊富なセットが用意されています。これらはすでにマテリアル テーマ設定に準拠しており、美しいマテリアル デザイン アプリの作成に役立ちます。デフォルトのプロパティを持つコンポーネントは、すぐに使用できます。

Button(onClick = { /*..*/ }) {
    Text(text = "My Button")
}

M3 では、強調と注意に応じてさまざまな役割で使用される同じコンポーネントの多くのバージョンが提供されています。

FAB ボタン、プライマリ ボタン、テキスト ボタンの順に強調度を下げていく
図 14。FAB、プライマリ、テキスト ボタンの順にボタンの強調度を下げます。
  • 最も重要なアクションの拡張フローティング操作ボタン:

ExtendedFloatingActionButton(
    onClick = { /*..*/ },
    modifier = Modifier
) {
    Icon(
        imageVector = Icons.Default.Edit,
        contentDescription = stringResource(id = R.string.edit),
    )
    Text(
        text = stringResource(id = R.string.add_entry),
    )
}

  • 高強調アクションの塗りつぶしボタン:

Button(onClick = { /*..*/ }) {
    Text(text = stringResource(id = R.string.view_entry))
}

  • 低強調アクションのテキスト ボタン:

TextButton(onClick = { /*..*/ }) {
    Text(text = stringResource(id = R.string.replated_articles))
}

マテリアル ボタンやその他のコンポーネントについて、詳しくはこちらをご覧ください。マテリアル 3 には、さまざまなユースケースや画面サイズに合わせて特別に設計された、ボタン、アプリバー、ナビゲーション コンポーネントなどの幅広いコンポーネント スイートが用意されています。

マテリアルには、さまざまな画面サイズと状態に応じて、ナビゲーションの実装に役立つナビゲーション コンポーネントもいくつか用意されています。

NavigationBar は、5 つ以下の宛先をターゲットにする場合に、コンパクト デバイスで使用されます。

NavigationBar(modifier = Modifier.fillMaxWidth()) {
    Destinations.entries.forEach { replyDestination ->
        NavigationBarItem(
            selected = selectedDestination == replyDestination,
            onClick = { },
            icon = { }
        )
    }
}

NavigationRail は、横向きモードの小規模から中規模のタブレットまたはスマートフォンで使用されます。ユーザーに人間工学に基づいた設計を提供し、デバイスのユーザー エクスペリエンスを向上させます。

NavigationRail(
    modifier = Modifier.fillMaxHeight(),
) {
    Destinations.entries.forEach { replyDestination ->
        NavigationRailItem(
            selected = selectedDestination == replyDestination,
            onClick = { },
            icon = { }
        )
    }
}

Reply の BottomNavigationBar(左)と NavigationRail(右)のショーケース
図 15. BottomNavigationBar(左)と NavigationRail(右)の返信ショーケース

デフォルトのテーマで両方を使用して、あらゆるデバイスサイズで没入感のあるユーザー エクスペリエンスを提供します。

NavigationDrawer は、詳細を表示するのに十分なスペースがある中型から大型のタブレットで使用されます。NavigationRail とともに PermanentNavigationDrawer または ModalNavigationDrawer を使用できます。

PermanentNavigationDrawer(modifier = Modifier.fillMaxHeight(), drawerContent = {
    Destinations.entries.forEach { replyDestination ->
        NavigationRailItem(
            selected = selectedDestination == replyDestination,
            onClick = { },
            icon = { },
            label = { }
        )
    }
}) {
}

固定的なナビゲーション ドロワーの返信ショーケース
図 16. 固定的なナビゲーション ドロワーの Reply のショーケース

ナビゲーション オプションは、ユーザー エクスペリエンス、人間工学、アクセシビリティを向上させます。マテリアル ナビゲーション コンポーネントについて詳しくは、Compose アダプティブ Codelab をご覧ください。

コンポーネントのテーマ設定をカスタマイズする

M3 は、パーソナライズと柔軟性を重視しています。すべてのコンポーネントにはデフォルトの色が適用されていますが、必要に応じて色をカスタマイズするための柔軟な API が公開されています。

カードやボタンなどのほとんどのコンポーネントには、色とエレベーションのインターフェースを公開するデフォルト オブジェクトが用意されています。このオブジェクトを変更して、コンポーネントをカスタマイズできます。

val customCardColors = CardDefaults.cardColors(
    contentColor = MaterialTheme.colorScheme.primary,
    containerColor = MaterialTheme.colorScheme.primaryContainer,
    disabledContentColor = MaterialTheme.colorScheme.surface,
    disabledContainerColor = MaterialTheme.colorScheme.onSurface,
)
val customCardElevation = CardDefaults.cardElevation(
    defaultElevation = 8.dp,
    pressedElevation = 2.dp,
    focusedElevation = 4.dp
)
Card(
    colors = customCardColors,
    elevation = customCardElevation
) {
    // m3 card content
}

詳しくは、Material 3 のカスタマイズをご覧ください。

システム UI

Material You の一部の要素は、Android 12 以降の新しい視覚的スタイルとシステム UI に由来します。変更点がある 2 つの主要な領域は、リップルとオーバースクロールです。これらの変更を実装するための追加の作業は不要です。

リップル

リップルでは、タップされた際にサーフェスを明るくするために、かすかなスパークルが使用されるようになりました。Compose マテリアルのリップルは内部的に Android のプラットフォーム RippleDrawable を使用しているため、Android 12 以降ではすべてのマテリアル コンポーネントでスパークル リップルを使用できます。

M2 と M3 のリップル
図 17. M2 と M3 のリップル

オーバースクロール

オーバースクロールでは、スクロール コンテナの端でストレッチ効果が使用されるようになりました。Compose Foundation 1.1.0 以降では、API レベルにかかわらず、スクロール コンテナのコンポーザブルでストレッチ オーバースクロールがデフォルトでオンになっています(LazyColumnLazyRowLazyVerticalGrid など)。

コンテナの端でストレッチ効果を使用してオーバースクロールする
図 18. コンテナの端でストレッチ効果を使用したオーバースクロール

ユーザー補助

マテリアル コンポーネントに組み込まれたユーザー補助の標準は、インクルーシブなプロダクト デザインの基盤となるように設計されています。プロダクトのユーザー補助機能を理解することで、弱視、失明、聴覚障がい、認知障がい、運動機能障がい、状況に応じた障がい(腕の骨折など)のあるユーザーを含む、すべてのユーザーのユーザビリティを向上させることができます。

色のアクセシビリティ

ダイナミック カラーは、色のコントラストに関するユーザー補助の基準を満たすように設計されています。色調パレット システムは、デフォルトでアクセスしやすいカラーパターンを簡単に作成するうえで重要です。

マテリアルのカラーシステムは、アクセス可能なコントラスト比を満たすために使用できる標準のトーン値と測定値を提供します。

返信サンプルアプリ: プライマリ、セカンダリ、ターシャリのトーン パレット(上から下)
図 19. 返信サンプルアプリ: プライマリ、セカンダリ、ターシャリのトーン パレット(上から下)

すべてのマテリアル コンポーネントと動的テーマ設定では、ユーザー補助要件を満たすように選択された色調パレットのセットから、上記のカラーロールがすでに使用されています。ただし、コンポーネントをカスタマイズする場合は、適切なカラーロールを使用し、不一致を回避してください。

プライマリでは on-primary、プライマリ コンテナでは on-primary-container を使用し、他のアクセント カラーやニュートラル カラーでも同様に、ユーザーにとってのコントラストを提供します。

プライマリの上に第 3 のコンテナを使用すると、コントラストの低いボタンが表示されます。

// ✅ Button with sufficient contrast ratio
Button(
    onClick = { },
    colors = ButtonDefaults.buttonColors(
        containerColor = MaterialTheme.colorScheme.primary,
        contentColor = MaterialTheme.colorScheme.onPrimary
    )
) {
}

// ❌ Button with poor contrast ratio
Button(
    onClick = { },
    colors = ButtonDefaults.buttonColors(
        containerColor = MaterialTheme.colorScheme.tertiaryContainer,
        contentColor = MaterialTheme.colorScheme.primaryContainer
    )
) {
}

十分なコントラスト(左)と不十分なコントラスト(右)
図 20。十分なコントラスト(左)と不十分なコントラスト(右)

タイポグラフィのユーザー補助機能

M3 のタイプスケールでは、静的なタイプランプと値が更新され、デバイス間でスケーリングされるサイズ カテゴリの簡素化された動的なフレームワークが提供されます。

たとえば、M3 では、ディスプレイの小サイズに、スマートフォンやタブレットなどのデバイス コンテキストに応じて異なる値を割り当てることができます。

大画面

マテリアルは、アプリのアクセシビリティを高め、大型デバイスを持つユーザーのエルゴノミクスを改善するために、アダプティブ レイアウトと折りたたみ式デバイスに関するガイダンスを提供します。

マテリアルは、大型デバイスで優れたユーザー エクスペリエンスを提供するためのさまざまな種類のナビゲーションを提供します。

Android の大画面アプリの品質に関するガイドラインの詳細と、アダプティブでアクセシブルなデザインの返信サンプルをご覧ください。

詳細

Compose のマテリアル テーマ設定の詳細については、以下のリソースをご覧ください。

サンプルアプリ

ドキュメント

API リファレンスとソースコード

動画