检测设备中是否存在Material You。

7
所以,我的老板让我分析如何从Android 12开始实现Material You颜色。我一直在研究,但每篇关于“如何做到这一点”的博客都告诉你,你需要按住主屏幕,然后进入“壁纸和样式”并更改壁纸。不过有一个问题。
我记得当Android 12处于Beta版时,它支持Material You颜色。然而(我认为)在正式发布后,此支持已被删除,因为我找不到该选项。当我按住主屏幕时,它看起来像这样:

image

当我点击“壁纸”时,它显示“壁纸”,但没有打开名为“壁纸和样式”的菜单,而是重定向到动态壁纸。我在正式的Android 12版本中找不到壁纸颜色选项。然而,在即将推出的API 32(我认为是Android 13)模拟器上可以找到该选项。
经过一番研究,我发现系统会在诸如system_accent1_600等系统资源下生成壁纸颜色,这些资源从API 31开始提供(更多信息here)。在使用API 32 beta模拟器时,这确实有效,但在API 31官方模拟器上默认为其他内容(强调色彩为蓝色,中性色彩为灰色,即背景色),我还没有找到来源。
问题是:
Material You颜色是否从Android 12(API 31)开始得到了官方支持?如果是,则为什么我无法在Android的官方模拟器上找到它?
此外,是否可以检测设备是否支持Material You颜色,并提供不同的选项?
2个回答

3
我认为这是您正在寻找的内容:

我认为这就是您要找的:

public static boolean isDynamicColorAvailable() 
{
    return VERSION.SDK_INT >= VERSION_CODES.S && DYNAMIC_COLOR_SUPPORTED_MANUFACTURERS.contains(Build.MANUFACTURER.toLowerCase());   
}

这段代码在com.google.android.material.color包的DynamicColors类中,您可以直接使用以下方式调用:

boolean isdca = DynamicColors.isDynamicColorAvailable();

我希望这个回答可以解决最后一个问题。

请告诉我在模拟器上运行此代码是否返回“true”或“false”。 - Sujal Kumar
是的,在API 31上确实会返回true,但问题仍然存在,因为无论壁纸是什么,都只应用默认的蓝色。 - DrHowdyDoo
你尝试在Application类的onCreate()方法中加入"DynamicColors.applyToActivitiesIfAvailable(this);"了吗? - Sujal Kumar
1
我只有一个活动,所以我使用了 DynamicColors.applyIfAvailable(this),它应用了蓝色。我正在使用 Theme.Material3.DayNight.NoActionBar - DrHowdyDoo
你说得对,这些模拟器目前还没有那些“Material You”功能。我们只能期待更新或者最后的选择是在安卓12+的物理设备上进行测试。 - Sujal Kumar
显示剩余5条评论

2

1. Material You颜色从Android 12(API 31)开始正式支持吗?

是的!但这取决于ROM的实现方式。如果你使用的是Pixel,你可以通过内置的壁纸应用程序更改颜色。但如果你使用AOSP,则没有官方的UI界面供用户更改。

查看这个文档:https://gist.github.com/zhaofengli/232f5a3d33113871ad61491629886084

2. 如果是,那么为什么我在Android的官方模拟器上找不到它呢?

看起来谷歌从镜像中删除了它。之前的镜像有这个功能。

3. 同时,是否可能检测设备是否支持Material You颜色?

由于Android 12正式支持Material You,所以你只需简单地检查api版本。 但是,根据第二个问题,某些系统仍不支持它,因此你可以使用方法com.google.android.material.color.DynamicColors#isDynamicColorAvailable。这是Material Design使用的明确方法,取决于SDK版本和手机制造商。

https://cs.github.com/material-components/material-components-android/blob/2ae3ca42985722900f53de9d9a1ef61c143767eb/lib/java/com/google/android/material/color/DynamicColors.java#L279-L289

4. 实现Material You的正确方法是什么?

  1. XML方式:遵循官方文档:https://m3.material.io/libraries/mdc-android/color-theming
  2. 以编程方式:

查看我的应用程序代码

val Context.colorOnPrimary: Int
    get() {
        return when {
            DynamicColors.isDynamicColorAvailable() -> {
                getColorFromAttr(R.attr.colorOnPrimary)
            }
            isNight() || !supportNight() -> {
                ContextCompat.getColor(this, R.color.md_theme_dark_onPrimary)
            }
            else -> {
                ContextCompat.getColor(this, R.color.md_theme_light_onPrimary)
            }
        }
    }

@ColorInt
fun Context.getColorFromAttr(
    @AttrRes attrColor: Int,
    typedValue: TypedValue = TypedValue(),
    resolveRefs: Boolean = true
): Int {
    theme.resolveAttribute(attrColor, typedValue, resolveRefs)
    return typedValue.data
}


1
感谢您提供有关第1、2和4个问题的信息,但是在第3个问题上,我忘记了询问一些额外的内容。我的意思是,是否可以检测到启用不同选项的Material You支持,例如壁纸颜色或基本颜色。已相应地编辑了问题。 - Furkan Yurdakul
1
@FurkanYurdakul 我认为你不需要检查是“壁纸颜色还是基本颜色”。在我看来,Android 12原生支持为整个系统设置颜色。这是壁纸的工作或某些自定义ROM功能。对于应用程序开发人员,我们只使用系统的颜色。壁纸的行为应该对我们的应用程序透明 :) - rosuh
1
@SujalKumar,“DynamicColors.applyifavailable()”可以为指定的活动应用动态颜色,但它仅适用于XML中的官方MD组件。如果您有一些自定义视图,它将不会自动应用于您的自定义视图。这就是为什么使用第4种解决方案以编程方式获取动态颜色。 - rosuh
@FurkanYurdakul 看起来你只能使用方法 com.google.android.material.color.DynamicColors#isDynamicColorAvailable。这是 Material Design 使用的判断方法,它取决于 SDK 版本和手机制造商。 - rosuh
完全正确,哈哈。 - Sujal Kumar
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接