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 側でコントラストの設定に合わせて色が調整されるので実装側で特別な対応は不要です。
リンク