为什么要自定义主题
primary: Color, primaryVariant: Color, secondary: Color, secondaryVariant: Color, background: Color, surface: Color, error: Color, onPrimary: Color, onSecondary: Color, onBackground: Color, onSurface: Color, onError: Color, isLight: Boolean 复制代码
上面代码中的颜色是系统默认主题中的颜色,他能满足我们大部分颜色的需求,不过对于庞大的业务来说总会有多余的颜色需要处理,并且也可能需要适配深色和亮色两种模式,在这种情况下自定义主题就很有必要了。
还有一点,系统默认主题提供的颜色字段无法与我们的业务属性关联。
如何定义
我们使用系统主题分类一样的方式来实现,通过两个apiCompositionLocalProvider
、compositionLocalOf
实现。这两个api适用的场景很少,主题中的使用是最常见的。
我们可以使用CompositionLocalProvider
包裹布局,compositionLocalOf
变量提供值,这样当值发生定义后,整个树内部的相关属性都可以统一改变。
部分代码
- 定义我们自定义的颜色类,包含两个变量,
colorBg
背景颜色,textColor
文字颜色
class CustomColor( colorBg: Color, textColor: Color, ) { val colorBg by mutableStateOf(colorBg) val textColor by mutableStateOf(textColor) } 复制代码
- 生成亮色和深色两个颜色集合
fun customDarkTheme( colorBg: Color = Color(0xFFA243B3), textColor: Color = Color.Green, ): CustomColor = CustomColor( colorBg, textColor ) fun customLightTheme( colorBg: Color = Color.White, textColor: Color = Color.Black, ): CustomColor = CustomColor( colorBg, textColor ) 复制代码
- 生成compositionLocalOf变量MultipleTheme
val MultipleTheme = compositionLocalOf<CustomColor> { customLightColor } 复制代码
如上代码是自定义主题颜色集合,下面是使用方法
- 在我们的根树部分使用CompositionLocalProvider包裹组合
CompositionLocalProvider(MultipleTheme provides if (isSystemInDarkTheme()) customDartColor else customLightColor) { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Greeting("Android") } } 复制代码
- 定义布局
@Composable fun Greeting(name: String) { Box(Modifier .fillMaxSize() .background(MultipleTheme.current.colorBg), contentAlignment = Alignment.Center) { Text(text = "公众号:安安安安卓", style = TextStyle(color = MultipleTheme.current.textColor, fontSize = 40.sp)) } } 复制代码
效果展示
- 深色
- 亮色