终究没有人在意一家民营企业的生死

去泰国看了一场“成人秀”,画面尴尬到让人窒息.....

网友建议:远离举报者李X夫!

【少儿禁】马建《亮出你的舌苔或空空荡荡》

10部适合女性看的唯美情色电影

生成图片,分享到微信朋友圈

自由微信安卓APP发布,立即下载! | 提交文章网址
查看原文

根据壁纸修改 App 主题,它真的来了 | 开发者说·DTalk

yechaoa Android 开发者 2022-10-12

本文原作者: yechaoa,原文发布于: 掘金

https://juejin.cn/post/7093158303684902948




前言



曾经产品经理的奇思妙想,现在终于可以实现了...



效果



效果中,原本是红色壁纸对应的红色 App 主题,在改成绿色壁纸之后,App 主题也相应的变成绿色了。



介绍



这个效果主要是使用了 Material You 中的动态颜色功能。


什么是 Material You


Material You 也称 Material 3 或 M3,是第三代 Material Design 设计语言。


Material You 将颜色重新定义为更加个性化的体验,助力于构建出色且富有表现力的应用。


什么是动态颜色


动态颜色 (Dynamic Color) 是 Material You 的关键部分,通过动态配色提取算法从用户的壁纸中派生出颜色方案,且符合无障碍使用的标准,亦或是自定义的个性化颜色方案,然后应用于系统 UI 和应用程序,从而让设备变得更加个性化。


动态颜色的原理是什么


  • 首先,从用户的壁纸上提取一种源颜色,并推算出 5 种关键颜色,比如 Primary、Secondary、Tertiary 等。
  • 然后,将每个关键颜色转化为由 13 种色调组成的调色板,且每种色调会生成对应的浅、深色方案。
  • 最后,通过系统 Token 将从壁纸提取的颜色方案和 App Theme 关联起来,在 DynamicColorsActivityLifecycleCallbacks 中判断是否需要覆盖。



实现



迁移到 M3


更新 Gradle 依赖

升级 material 库版本到 1.5.0 及以上

implementation 'com.google.android.material:material:1.5.0'


修改版本

修改 compileSdkVersiontargetSdkVersion31 及以上

android { compileSdkVersion 31 defaultConfig { applicationId "com.yechaoa.materialdesign" minSdkVersion 23 targetSdkVersion 31 ... } ... }

备注: 在 Android 12 上,为增强安全性,需要对所有的四大组件 (带有 intent-filter) 添加 android:exported 属性。


修改 App 主题

Theme.AppCompat.*Theme.MaterialComponents.* 改为 Theme.Material3.*

<style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar"></style>

添加动态颜色


应用动态颜色

class App: Application() {
override fun onCreate() { super.onCreate()
// apply dynamic color DynamicColors.applyToActivitiesIfAvailable(this) }}


Application 中应用动态颜色能力,除 applyToActivitiesIfAvailable(@NonNull Application application) 方法之外主要还有: 
  • applyToActivitiesIfAvailable(@NonNull Application application, @StyleRes int theme) 第二个参数表示自定义的覆盖系统的 theme

  • applyIfAvailable(@NonNull Activity activity) 或是某一个 Activity

  • applyIfAvailable(@NonNull Activity activity, @StyleRes int theme) 或是只有某一个 Activity 覆盖

  • 等等


这里直接整个 App 都使用动态颜色。也可以在 App 中通过开关的形式来决策。


注册到 manifest

通过 android:name 来注册我们自定义的 Application

<application android:name=".App" ... android:theme="@style/AppTheme"> ...    </application>


使用动态颜色

我们过去在使用颜色时可能是硬编码,比如这样: 

android:background="@color/colorPrimary"


现在颜色的色值不确定了,应改为动态访问的方式: 

android:background="?attr/colorPrimary"


OK,至此已经可以在 Android 12 上试试动态颜色的效果了。


Material Theme Builder


在上文 "应用动态颜色" 这部分中,我们提到 applyIfAvailable(@NonNull Activity activity, @StyleRes int theme),可以通过第二个参数只给某一个 Activity 覆盖 Theme。


场景还是有很多的,比如某个特殊的页面就是需要不一样的主题,再比如在国庆节这天 App 的首页一定要是红色的。


官方其实也考虑到了这种场景,并提供了 Material Theme Builder (Figma&Web) 工具进行可视化自定义。


下面主要介绍 Material Theme Builder 在 Web 上的使用。


  • Material Theme Builder
    https://m3.material.io/theme-builder#/dynamic

壁纸预览
截图是自带的效果,在右下角可以点击 add your wallpaper 添加您的壁纸并查看显示效果。

自定义 Theme

点击顶部的 CUSTOM Tab 可以进入自定义页面。

左边的核心颜色可以自定义修改,并可以添加扩展颜色。

中间是实时效果,右边是调色板。


在右上角有一个 EXPORT 导出按钮

除了可以应用 Android,还有 FlutterWeb


导出的文件包含日间模式和夜间模式的 Color 和 Theme 文件,可以直接 copy 到项目中使用。


Theme 覆盖

基于规范,覆盖的主题最好是加上 overlay 标示,比如:

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight"> <item name="colorPrimary">@color/overlay_colorPrimary</item> ...</style>

代码应用:

DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme.Overlay)


也可以添加一个开关,让用户可以在动态颜色和自定义颜色来回切换。


是否支持动态颜色


基于 Android 的开源,可能并不是每个厂商的 Android 12 设备都支持动态颜色。


所以官方也提供了 API 进行判断:

@SuppressLint("DefaultLocale") @ChecksSdkIntAtLeast(api = VERSION_CODES.S) public static boolean isDynamicColorAvailable() { if (VERSION.SDK_INT < VERSION_CODES.S) { return false; } DeviceSupportCondition deviceSupportCondition = DYNAMIC_COLOR_SUPPORTED_MANUFACTURERS.get(Build.MANUFACTURER.toLowerCase()); if (deviceSupportCondition == null) { deviceSupportCondition = DYNAMIC_COLOR_SUPPORTED_BRANDS.get(Build.BRAND.toLowerCase()); } return deviceSupportCondition != null && deviceSupportCondition.isSupported();  }


截止目前,跟进的厂商有:

deviceMap.put("oppo", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("realme", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("oneplus", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("vivo", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("xiaomi", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("motorola", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("itel", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("tecno mobile limited", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("infinix mobility limited", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("hmd global", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("sharp", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("sony", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("tcl", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("lenovo", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("lge", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("google", DEFAULT_DEVICE_SUPPORT_CONDITION); deviceMap.put("robolectric", DEFAULT_DEVICE_SUPPORT_CONDITION);    deviceMap.put("samsung", SAMSUNG_DEVICE_SUPPORT_CONDITION);


总结



总的来说,这个功能还是非常 nice 的,可以让您的 App 在 Android 12 上表现的更加个性化且富有表现力。
但还是能识别出很多成本的,比如 targetSdkVersion 升级到 31,Theme 迁移到 Material 3,以及升级后的整包回归。

所以,个人建议,对于老项目最好是申请专项来做,其实更建议用新项目来尝鲜。



参考文档



  • Github
    https://github.com/yechaoa/MaterialDesign
  • Migrating to Material Design 3
    https://material.io/blog/migrating-material-3
  • Material Design 3
    https://m3.material.io/
  • Material Theme Builder
    https://m3.material.io/theme-builder#/dynamic
  • DynamicColors
    https://developer.android.google.cn/reference/com/google/android/material/color/DynamicColors





长按右侧二维码

查看更多开发者精彩分享




"开发者说·DTalk" 面向中国开发者们征集 Google 移动应用 (apps & games) 相关的产品/技术内容。欢迎大家前来分享您对移动应用的行业洞察或见解、移动开发过程中的心得或新发现、以及应用出海的实战经验总结和相关产品的使用反馈等。我们由衷地希望可以给这些出众的中国开发者们提供更好展现自己、充分发挥自己特长的平台。我们将通过大家的技术内容着重选出优秀案例进行谷歌开发技术专家 (GDE) 的推荐。




 点击屏末 | 阅读原文 | 即刻报名参与 "开发者说·DTalk" 



文章有问题?点此查看未经处理的缓存