theme: channing-cyan
设置Material主题
Material主题主要包含三个属性: 颜色、排版和形状,API如下:
@Composable fun MaterialTheme( colors: Colors = MaterialTheme.colors, // 颜色集合 typography: Typography = MaterialTheme.typography, // 排版集合 shapes: Shapes = MaterialTheme.shapes, // 形状集合 content: @Composable () -> Unit // 要展示的内容 )
颜色
class Colors( primary: Color, // 主颜色,屏幕和元素都用这个颜色 primaryVariant: Color, // 用于区分主颜色,比如app bar和system bar secondary: Color, // 强调色,悬浮按钮,单选/复选按钮,高亮选中的文本,链接和标题 secondaryVariant: Color, // 用于区分强调色 background: Color, // 背景色,在可滚动项下面展示 surface: Color, // 表层色,展示在组件表层,比如卡片,清单和菜单(CardView,SheetLayout,Menu)等 error: Color, // 错误色,展示错误信息,比如TextField的提示信息 onPrimary: Color, // 在主颜色primary之上的文本和图标的颜色 onSecondary: Color, // 在强调色secondary之上的文本和图标的颜色 onBackground: Color, // 在背景色background之上的文本和图标的颜色 onSurface: Color, // 在表层色surface之上的文本和图标的颜色 onError: Color, // 在错误色error之上的文本和图标的颜色 isLight: Boolean // 是否是浅色模式 )
排版
class Typography internal constructor( val h1: TextStyle, // 一级标题 val h2: TextStyle, val h3: TextStyle, val h4: TextStyle, val h5: TextStyle, val h6: TextStyle, val subtitle1: TextStyle, // 一级副标题 val subtitle2: TextStyle, val body1: TextStyle, // 一级内容 val body2: TextStyle, val button: TextStyle, // 按钮使用 val caption: TextStyle, // 说明文字 val overline: TextStyle // 页眉/页脚 )
这里主要定义了各级标题/副标题,以及内容区的字体属性,至于TextStyle的具体属性可以看这里: Compose中的Text
形状
``` class Shapes(
// 小组件使用的形状,比如: Button,SnackBar,悬浮按钮等 val small: CornerBasedShape = RoundedCornerShape(4.dp),
// 中组件使用的形状,比如Card(就是CardView),AlertDialog等 val medium: CornerBasedShape = RoundedCornerShape(4.dp),
// 大组件使用的形状,比如ModalDrawer或者ModalBottomSheetLayout(就是抽屉布局和清单布局) val large: CornerBasedShape = RoundedCornerShape(0.dp) ) ```
使用
现在让我们来try try,首先我们来定义颜色,代码如下:
// 定义深色模式下使用的颜色 private val DarkColorPalette = darkColors( primary = Color.White, onPrimary = Color.Red, secondary = Color.Black, surface = Color.Green, ) // 定义浅色模式下使用的颜色 private val LightColorPalette = lightColors( primary = Color.Black, onPrimary = Color.Yellow, secondary = Color.White, surface = Color.Blue )
代码很简单,只定义了深色和浅色模式下的几种颜色,其实Compose已经内置有颜色可供使用了,比如代码中的darkColors
和lightColors
,可以自行翻阅源码查看,里面只是提供了颜色参考。比如darkColors
:
fun darkColors( primary: Color = Color(0xFFBB86FC), primaryVariant: Color = Color(0xFF3700B3), secondary: Color = Color(0xFF03DAC6), secondaryVariant: Color = secondary, background: Color = Color(0xFF121212), surface: Color = Color(0xFF121212), error: Color = Color(0xFFCF6679), onPrimary: Color = Color.Black, onSecondary: Color = Color.Black, onBackground: Color = Color.White, onSurface: Color = Color.White, onError: Color = Color.Black )
接着,我们来定义形状,代码如下:
val Shapes = Shapes( small = RoundedCornerShape(4.dp), medium = RoundedCornerShape(8.dp), large = RoundedCornerShape(16.dp) )
我们根据不同大小的形状,设置不同的圆角,当然你也可以设置颜色、四个角的单独尺寸等。
接着,我们来定义排版,代码如下:
val Typography = Typography( body1 = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 16.sp ), button = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.W500, fontSize = 14.sp ), )
我们只定义了body1
和button
,有兴趣的也可以试试其他的(感觉这属性没什么卵用)。
好,现在让我们用起来,我们添加如下代码:
@Composable fun ComposeTourTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { // 根据不同模式使用不同颜色值 val colors = if (darkTheme) { DarkColorPalette } else { LightColorPalette } MaterialTheme( colors = colors, typography = Typography, shapes = Shapes, content = content ) }
逻辑很简单,就只直接调用MaterialTheme
来传入我们定义的颜色、形状和排版,这里可以使用isSystemInDarkTheme()
来判断当前是否是深色模式,如果是深色模式,就使用深色主题,否则就用浅色主题。
最后,在Activity里面调用:
setContent { ComposeTourTheme { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { // 添加一个Card Card(modifier = Modifier.padding(bottom = 16.dp)) { // 在Card里面添加一个CheckBox,设置边距为32dp Checkbox(checked = true, onCheckedChange = {}, modifier = Modifier.padding(32.dp)) } // 添加一个Button Button(onClick = { Toast.makeText(this@MainActivity, "click button", Toast.LENGTH_SHORT).show() }) { Text(text = "Button") } } } }
很简单,我们添加一个Card(就是CardView),在Card里面添加一个CheckBox,然后添加一个Button。现在让我们来看看效果:
可以看到,切换了深色主题后,颜色会自动跟着改变,并且Card的背景圆角和Button的背景圆角也是不一样的,这是因为Card默认用的是medium尺寸,而Button默认用的是small尺寸。当然,其他属性你也可以自己去尝试。
一句话,主题就是在形状、颜色和排版方面,给app一个宏观的,粗粒度的统一,可以快速切换app的整体风格,当然,如果你要具体到每一个控件,那么主题是不适用的,你需要针对每个控件去对Modifier做具体定制,这里不再废话。