【问题标题】:Detect if Material You is present in device检测您的材料是否存在于设备中
【发布时间】:2021-12-29 13:56:39
【问题描述】:

所以,我的老板让我分析从Android 12开始如何实现Material You颜色。我一直在研究它,每个关于“如何做”的页面的每个博客都告诉你,你需要持有在主屏幕下,然后转到“壁纸和样式”并更改您的壁纸。不过有一个问题。

我记得 Android 12 处于 Beta 版时,它支持 Material You 颜色。但是(我假设)在正式发布后,此支持已被删除,因为我无法找到该选项。这是我在主屏幕按住时的样子:

它显示“壁纸”,当我点击它时,它没有打开一个名为“壁纸和样式”的菜单,它只是重定向到动态壁纸。我在 Android 12 官方版本中找不到壁纸颜色选项。但是,它存在于即将推出的 API 32(我相信是 Android 13)模拟器上。

经过一番研究,我发现系统在system_accent1_600等系统资源下生成壁纸颜色,这些资源从API 31开始可用(更多信息here)。当我使用处于测试阶段的 API 32 仿真器时,这确实有效,但它默认为我还没弄清楚从哪里来在 API 31 官方模拟器上。

问题来了:

从 Android 12 (API 31) 开始,官方支持 Material You 颜色吗?如果是,那为什么我在安卓官方模拟器上找不到呢?

另外,是否可以检测设备是否支持 Material You 颜色不同的选项

【问题讨论】:

    标签: android material-design material-you


    【解决方案1】:

    我想这就是你要找的:

    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”。
    • 是的,这确实在 api 31 上返回 true,但问题仍然存在,因为无论壁纸如何,都只应用默认蓝色。
    • 您是否尝试添加“DynamicColors.applyToActivitiesIfAvailable(this);”在应用程序类的 onCreate() 中?
    • 另外,您使用的是哪个主题?样式中预定义的颜色是什么?
    • 我有一个活动,所以我使用了DynamicColors.applyIfAvailable(this),它正在应用蓝色。我正在使用Theme.Material3.DayNight.NoActionBar
    【解决方案2】:

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

    是的!但它基于ROM的实现方式。如果您使用 Pixel,您可以通过内置的壁纸应用程序更改颜色。但是,如果您使用的是 AOSP,那么用户界面中没有正式的方式可以让用户更改它。

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

    2。如果是,那为什么我在安卓官方模拟器上找不到呢?

    Google 似乎已将其从镜像中删除。以前的镜子有这个功能。

    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. 以编程方式:

    查看我的app's code

    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、第 2 和第 4 个问题的信息,但在第 3 个问题上,我忘了问一些额外的问题,我的意思是是否可以通过启用不同的选项来检测您支持的材料,也就是壁纸颜色或基本颜色。相应地编辑了问题。
    • @FurkanYurdakul 我认为您不需要检查是“壁纸颜色还是基本颜色”。在我看来,Android 12 原生支持为整个系统设置颜色。那是壁纸的工作或某些自定义 ROM 功能。对于应用程序开发人员,我们只使用系统的颜色。壁纸的行为对我们的应用程序应该是透明的 :)
    • 这段代码是否等同于DynamicColors.applyifavailable()?
    • 或者我们需要像这样明确地这样做只是为了根据口味进行定制?
    • @SujalKumar DynamicColors.applyifavailable() 可以为指定活动应用动态颜色,但它仅适用于 xml 中的官方 MD 组件。如果您有一些自定义视图,它将不会自动应用于您的自定义视图。这就是为什么使用 No.4 解决方案以编程方式获取动态颜色的原因。
    猜你喜欢
    • 2015-05-31
    • 2015-11-11
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2020-01-28
    相关资源
    最近更新 更多