产品经理的奇思妙想:根据手机壁纸自动切换App主题,真的来了
Posted River_ly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了产品经理的奇思妙想:根据手机壁纸自动切换App主题,真的来了相关的知识,希望对你有一定的参考价值。
作者:yechaoa
曾经产品经理的奇思妙想,现在终于可以实现了…
一、效果
效果中,原本是红色壁纸对应的红色App主题,在改成绿色壁纸之后,App主题也相应的变成绿色了。
模拟器演示略微小卡…
二、介绍
这个效果主要是使用了Material You中的动态颜色功能。
2.1、什么是Material You?
Material You也称Material3或M3,是第三代Material Design设计语言。
Material You将颜色重新定义为更加个性化的体验,助力于构建出色且富有表现力的应用。
2.2、什么是动态颜色?
动态颜色(Dynamic Color)是Material You的关键部分,通过动态配色提取算法从用户的壁纸中派生出颜色方案,且符合无障碍使用的标准,亦或是自定义的个性化颜色方案,然后应用于系统UI和应用程序,从而让设备变得更加个性化。
2.3、动态颜色的原理是什么?
首先,从用户的壁纸上提取一种源颜色,并推算出5种关键颜色,比如primary、Secondary、Tertiary等。
然后,将每个关键颜色转化为由13种色调组成的调色板,且每种色调会生成对应的浅、深色方案。
最后,通过系统Token将从壁纸提取的颜色方案和App Theme关联起来,在DynamicColorsActivityLifecycleCallbacks中判断是否需要覆盖。
三、实现
3.1、迁移到M3
- 3.1.1、更新Gradle依赖
升级material库版本到1.5.0及以上
implementation 'com.google.android.material:material:1.5.0'
- 3.1.2、修改版本
修改compileSdkVersion和targetSdkVersion到31及以上。
android
compileSdkVersion 31
defaultConfig
applicationId "com.yechaoa.materialdesign"
minSdkVersion 23
targetSdkVersion 31
...
...
备注:在Android12上,为增强安全性,需要对所有的四大组件(带有intent-filter)添加android:exported属性。
- 3.1.3、修改App主题
将Theme.AppCompat.或Theme.MaterialComponents. 改为Theme.Material3.*
<style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar"></style>
3.2、添加动态颜色
- 3.2.1、应用动态颜色
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中通过开关的形式来决策。
- 3.2.2、注册到manifest
通过android:name来注册我们自定义的Application。
<application
android:name=".App"
...
android:theme="@style/AppTheme">
...
</application>
- 3.2.3、使用动态颜色
我们过去在使用颜色时可能是硬编码,比如这样:
android:background="@color/colorPrimary"
现在颜色的色值不确定了,应改为动态访问的方式:
android:background="?attr/colorPrimary"
OK,至此已经可以在Android 12 上试试动态颜色的效果了。
3.3、Material Theme Builder
在3.2.1中,我们提到applyIfAvailable(@NonNull Activity activity, @StyleRes int theme) ,可以通过第二个参数只给某一个Activity覆盖Theme。
场景还是有很多的,比如某个特殊的页面就是需要不一样的主题,再比如在国庆节这天App的首页一定要是红色的。
官方其实也考虑到了这种场景,并提供了Material Theme Builder(Figma&Web)工具进行可视化自定义。
下面主要介绍 Material Theme Builder 在Web上的使用。
https://material-foundation.github.io/material-theme-builder/#/dynamic
- 3.3.1、壁纸预览
截图是自带的效果,在右下角可以点击add your wallpaper添加你的壁纸并查看显示效果。
- 3.3.2、自定义Theme
点击顶部的CUSTOM Tab可以进入自定义页面。
左边的核心颜色可以自定义修改,并可以添加扩展颜色。
中间是实时效果,右边是调色板。
在右上角有一个EXPORT导出按钮
除了可以应用Android,还有Flutter和Web。
导出的文件包含日间模式和夜间模式的Color和Theme文件,可以直接copy到项目中使用。
- 3.3.3、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)
也可以添加一个开关,让用户可以在动态颜色和自定义颜色来回切换。
3.4、是否支持动态颜色
基于Android的开源,可能并不是每个厂商的Android12设备都支持动态颜色。
所以官方也提供了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在Android12上表现的更加个性化且富有表现力。
但还是能识别出很多成本的,比如targetSdkVersion升级到31,Theme迁移到Material3,以及升级后的整包回归。
所以,个人建议,对于老项目最好是申请专项来做,其实更建议用新项目来尝鲜。
GitHub:
https://github.com/yechaoa/MaterialDesign
在这里也给大家分享一套完备的知识体系,整体参照了各家一线大厂高工岗位的招聘要求及岗位技能需求,并且每个具体的知识节点还附带有一整套体系化的学习资料、笔记进行辅助,不管你是从0到1还是从1到100,都可以很好的帮助你掌握知识原理,将所学的知识点全部串联起来
需要完整文档的朋友们可以顺手帮我点赞评论一下,直接前往公号:Android开发之家,自行领取。
由于篇幅原因没有一一贴上来,需要完整文档的朋友们可以顺手帮我点赞评论一下,直接前往公号:Android开发之家,自行领取。
以上是关于产品经理的奇思妙想:根据手机壁纸自动切换App主题,真的来了的主要内容,如果未能解决你的问题,请参考以下文章