2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Android 14以降の色のコントラスト機能をサポートする

Posted at

Android 14 以降では OS での設定として色のコントラストを 3 段階に設定することができ、Android 14 では 開発者向けオプションでのみ設定可能だったものが、Android 15 以降では正式な機能になります。
この機能は各アプリで対応する必要があるものとなっています。

ここではその対応をどのように実装するのかについて書いてます。

 
色のコントラストごとの見え方の違い
デフォルト

前提

Material Design 3 を使用している必要があります。
個別に色をコントラストチェッカーにかけて定義していくことも可能ですが、ものすごい工数がかかるので基本的には Material Theme Builder で生成した Color Theming を使うことをおすすめします。

Jetpack Compose の場合

UiModeManager.contrast で現在 OS 側で設定されているコントラストの値を取得できるので、その値を元に Theming を分岐させます。
ここで使用している Theming の定義は Material Theme Builder を使って生成されるコードに含まれるものとなります。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    when (uiModeManager.contrast) {
        in 0.0f..0.33f -> if (isDarkTheme) darkScheme else lightScheme
        in 0.34f..0.66f -> if (isDarkTheme) mediumContrastDarkColorScheme else mediumContrastLightColorScheme
        in 0.67f..1.0f -> if (isDarkTheme) highContrastDarkColorScheme else highContrastLightColorScheme
        else -> if (isDarkTheme) darkScheme else lightScheme
    }
}

Dynamic Color の設定なども含めると、Theming の設定するコードはこのようになります。

@Composable
fun AppTheme(
    isDarkTheme: Boolean,
    isDynamicColor: Boolean,
    content: @Composable () -> Unit
) {
    val context = LocalContext.current
    val uiModeManager = context.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
    val colorScheme =
        if (!isDynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            when (uiModeManager.contrast) {
                in 0.0f..0.33f -> if (isDarkTheme) darkScheme else lightScheme
                in 0.34f..0.66f -> if (isDarkTheme) mediumContrastDarkColorScheme else mediumContrastLightColorScheme
                in 0.67f..1.0f -> if (isDarkTheme) highContrastDarkColorScheme else highContrastLightColorScheme
                else -> if (isDarkTheme) darkScheme else lightScheme
            }
        } else if (isDynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (isDarkTheme) {
                dynamicDarkColorScheme(context)
            } else {
                dynamicLightColorScheme(context)
            }
        } else {
            if (isDarkTheme) darkScheme else lightScheme
        }

    MaterialTheme(
        colorScheme = colorScheme,
        ...
        content = content,
    )
}

material-components(AndroidView) の場合

material-components に ColorContrast の Util クラスが用意されているので、Material Theme Builder で生成されたコントラスト用の ThemeOverlay の style を設定すれば Android 14 以降で Color Contrast が使用可能な場合に適用してくれます。

ColorContrast.applyToActivitiesIfAvailable(
    application,
    ColorContrastOptions.Builder()
        .setMediumContrastThemeOverlay(R.style.ThemeOverlay_AppTheme_MediumContrast)
        .setHighContrastThemeOverlay(R.style.ThemeOverlay_AppTheme_HighContrast)
        .build()
)

Dynamic Color 使用時

Dynamic Color を使っているときは Dynamic color 側でコントラストの設定に合わせて色が調整されるので実装側で特別な対応は不要です。

リンク

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?