-
colorPrimary:主要品牌颜色,一般用于ActionBar背景
-
colorPrimaryDark:默认用于顶部状态栏和底部导航栏
-
colorPrimaryVariant:主要品牌颜色的可选颜色
-
colorSecondary:第二品牌颜色
-
colorSecondaryVariant:第二品牌颜色的可选颜色
-
colorPrimarySurface:对应Light主题指向colorPrimary,Dark主题指向colorSurface
-
colorOn[Primary, Secondary, Surface …],在Primary等这些背景的上面内容的颜色,例如ActioBar上面的文字颜色
-
colorAccent:默认设置给colorControlActivated,一般是主要品牌颜色的明亮版本补充
-
colorControlNormal:图标和控制项的正常状态颜色
-
colorControlActivated:图标和控制项的选中颜色(例如Checked或者Switcher)
-
colorControlHighlight:点击高亮效果(ripple或者selector)
-
colorButtonNormal:按钮默认状态颜色
-
colorSurface:cards, sheets, menus等控件的背景颜色
-
colorBackground:页面的背景颜色
-
colorError:展示错误的颜色
-
textColorPrimary:主要文字颜色
-
textColorSecondary:可选文字颜色
Tips: 当某个属性同时可以通过 ?attr/xxx 或者?android:attr/xxx获取时,最好使用?attr/xxx,因为?android:attr/xxx是通过系统获取,而?attr/xxx是通过静态库类似于AppCompat 或者 Material Design Component引入的。使用非系统版本的属性可以提高平台通用性。
如果需要自定义主题颜色,我们可以对颜色分别定义notnight和night两份,放在values以及values-night资源文件夹中,并在自定义主题时,传入给对应的颜色属性。例如:
res/values/styles.xml
res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>#4D71FF
#FFFFFF
#101214
#E0A62E
res/values-night/colors.xml
<?xml version="1.0" encoding="utf-8"?>#FF584D
#0B0C0D
#F5F7FA
#626469
控件切换颜色
同样的,我们可以在布局的XML文件中直接使用定义好的颜色值,例如
<TextView
android:id="@+id/auto_color_text"
android:text=“自定义变色文字”
android:background="@drawable/bg_text"
android:textColor="@color/color_text_0" />
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android=“http://schemas.android.com/apk/res/android”
android:shape=“rectangle”>
这样这个文字就会在深色模式中展示为黑底白字,在非深色模式中展示为白底黑字。
动态设置颜色
如果需要代码设置颜色,如果色值已经设置过notnight和night两份,那么直接设置颜色就可以得到深色模式变色效果。
auto_color_text.setTextColor(ContextCompat.getColor(this, R.color.color_text_0))
如果色值是从服务接口获取,那么可以使用上述深色模式的判断设置。
auto_color_text.setTextColor(if (isNightMode()) {
Color.parseColor(darkColorFromNetwork)
} else {
Color.parseColor(colorFromNetwork)
})
3. 图片&动画
普通图片&Gif图片
将图片分为明亮模式和深色模式两份,分别放置在drawable-night-xxx以及drawable-xxx文件夹中,并在view中直接使用即可,当深色模式切换时,会使用对应深色模式的资源。如下图所示:
在Vector资源定义时,通过指定画笔颜色来实现对深色模式的适配,例如:
<vector xmlns:android=“http://schemas.android.com/apk/res/android”
android:width=“24dp”
android:height=“24dp”
android:tint="@color/color_light"
android:viewportWidth=“24”
android:viewportHeight=“24”>
<path
android:fillColor="@android:color/white"
android:pathData=“M6.29,14.29L9,17v4c0,0.55 0.45,1 1,1h4c0.55,0 1,-0.45 1,-1v-4l2.71,-2.71c0.19,-0.19 0.29,-0.44 0.29,-0.71L18,10c0,-0.55 -0.45,-1 -1,-1L7,9c-0.55,0 -1,0.45 -1,1v3.59c0,0.26 0.11,0.52 0.29,0.7zM12,2c0.55,0 1,0.45 1,1v1c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1L11,3c0,-0.55 0.45,-1 1,-1zM4.21,5.17c0.39,-0.39 1.02,-0.39 1.42,0l0.71,0.71c0.39,0.39 0.39,1.02 0,1.41 -0.39,0.39 -1.02,0.39 -1.41,0l-0.72,-0.71c-0.39,-0.39 -0.39,-1.02 0,-1.41zM17.67,5.88l0.71,-0.71c0.39,-0.39 1.02,-0.39 1.41,0 0.39,0.39 0.39,1.02 0,1.41l-0.71,0.71c-0.39,0.39 -1.02,0.39 -1.41,0 -0.39,-0.39 -0.39,-1.02 0,-1.41z” />
其中android:tint为叠加颜色,@color/color_light已经分别定义好了notnight和night的色值。
Lottie
对于Lottie动画,我们可以使用Lottie的Dynamic Properties特性来针对深色模式进行颜色变化。例如我们有以下两个动画,左边是由颜色填充的机器人,右边是由描边生成的正在播放动画,我们可以调用LottieAnimationView.resolveKeyPath()方法获取动画的路径。
lottie_android_animate.addLottieOnCompositionLoadedListener {
lottie_android_animate.resolveKeyPath(KeyPath("**")).forEach {
Log.d(TAG, it.keysToString())
}
setupValueCallbacks()
}
对于机器小人打印的KeyPath如下:
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [MasterController]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [Head]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [Head, Group 3]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [Head, Group 3, Fill 1]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [Blink]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [Blink, Rectangle 2]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androiddarkthemedemo D/DarkThemeDemo: [Blink, Rectangle 2, Rectangle Path 1]
2020-09-10 15:30:55.762 29281-29281/com.shengj.androi