使用Material design 设计主题Theme

在Android中可以对整个应用的风格(颜色,字体等等)进行管理,这种风格叫做主题。通过主题对整个应用的字体、颜色、大小、形状进行管理可以使整个应用变得容易维护,保证App视觉的一致性。
Compose 的 Theme 摆脱了对 XML 的使用。Theme 一般会作为最顶层的 Composalbe 出现,所有内部 Composalbe 都会应用当前主题的配置。这样使得主题切换也变得非常容易。

Material主题设置是一种系统化的方法,用于自定义Material Design以更好反映产品的品牌,它是由颜色、排版和形状属性组成。如果这些属性被定义,构建应用的组件就会展现出对应属性的效果。
在Jetpack Compose中使用MaterialTheme可组合项来实现这些概念。

简单使用

例如根据系统Dark/Light主题,设置不同颜色

  1. 定义好深色模式和浅色模式的颜色值,定义自定义的Theme方法,根据将不同的状态传入深色还是浅色值:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /*定义深色模式的颜色值*/
    private val DarkColorPalette = darkColors(
    primary = Teal200,
    primaryVariant = Purple700,
    secondary = Teal200
    )
    /*定义浅色模式的颜色值*/
    private val LightColorPalette = lightColors(
    primary = Purple200,
    primaryVariant = Purple700,
    secondary = Teal200
    )
    /*定义一个自定的主题方法调用MaterialTheme*/
    @Composable
    fun ComposeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
    /*根据传递的参数判断配置深色还是浅色*/
    val colors = if (darkTheme) {
    DarkColorPalette
    } else {
    LightColorPalette
    }
    MaterialTheme(
    colors = colors,
    typography = Typography,
    shapes = Shapes,
    content = content
    )
    }
  2. 将自定义的Theme作为最顶层的 Composalbe,这样我们就可以在在内层的组件中使用定义好的.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class ThemeActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
    ComposeTheme(darkTheme = false) {
    Box(
    Modifier
    .size(200.dp, 200.dp)
    .background(MaterialTheme.colors.primary)
    ) {
    }
    }
    }
    }
    }
    上述代码ComposeComingTheme 该组合函数在 MaterialTheme 上构建而成,MaterialTheme由colors、typography、shapes属性组成。
    然后该组合函数默认根据系统 是否是暗黑主题 将 颜色属性 进行了不同的定义。如果是暗黑主题使用DarkColorPalette,
    否则使用LightColorPalette。darkColors和lightColors都继承自Colors,并有相关的默认颜色值。

主题自带颜色

1
2
3
4
5
6
7
8
9
10
11
12
primary: Color = Color(0xFF6200EE),
primaryVariant: Color = Color(0xFF3700B3),
secondary: Color = Color(0xFF03DAC6),
secondaryVariant: Color = Color(0xFF018786),
background: Color = Color.White,
surface: Color = Color.White,
error: Color = Color(0xFFB00020),
onPrimary: Color = Color.White,
onSecondary: Color = Color.Black,
onBackground: Color = Color.Black,
onSurface: Color = Color.Black,
onError: Color = Color.White

UI组件类型

虽然Jetpack Compose 1.0 才刚面世,但实际上其UI组件库已经十分完备,几乎完全覆盖了Android现有视图系统的所有组件及能力,主要包括:

  • 基础UI组件,如Button、TextView等,连Card、Fab、AppBar等Material Designe的控件都会涵盖;
  • 列表类组件,如List等,采用items{…} 中创建每条项目的 Composalbe,避免了额外的Adapter适配;
  • 布局类组件,提供了多种容器类Composalbe,可以十分高效方便地对子组件进行布局;通过一系列链式调用的Modifier操作符来装饰 Composable 的外观。操作符的使用十分丰富,如size、backgrounds、padding等;
  • 动画组件,同样是采用状态(State)驱动进行动画效果的实现。

Text

  • text 文字
  • color 文字颜色
  • fontSize 字体大小
  • fontStyle 字体样式, 可设置为斜体Italic
  • fontWeight 字体权重,可设置字体加粗
  • overflow 文字溢出效果,与maxLines结合使用可实现文字溢出显示省略号效果
  • maxLines 最大行数 ,与overflow结合使用实现文字溢出显示省略号效果

Button组件

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
@Composable
fun Button(
onClick: () -> Unit,// 按钮的点击事件
modifier: Modifier = Modifier,
enabled: Boolean = true, //是否启用
interactionState: InteractionState = remember { InteractionState() },
elevation: ButtonElevation? = ButtonDefaults.elevation(),//海拔
shape: Shape = MaterialTheme.shapes.small,//形状
border: BorderStroke? = null,//边框
colors: ButtonColors = ButtonDefaults.buttonColors(),//颜色
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,//内边距
content: @Composable RowScope.() -> Unit //内容组件
) { ... }

示例

Button 组件点击事件 onClick 和内容组件 content 是必填参数外。

1
2
3
4
5
6
@Composable
fun TestButton() {
Button(onClick = {/*TODO点击事件*/ }) {
Text(text = "button")
}
}

Image组件

源码

1
2
3
4
5
6
7
8
9
10
11
12
@Composable
fun Image(
bitmap: ImageBitmap,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
) {
...
}

属性

Image 对应于 Android View 的 ImageView,可以用来显示图片,它主要有以下属性:

  • bitmap: ImageBitmap:可以直接传入 ImageBitmap 构建,如想显示 drawable 文件夹下的图片,可以通过 var imageBitmap = ImageBitmap.imageResource(id = R.drawable.xxx)
  • contentDescription: String?:accessibility services 用于辅助功能时提示给用户的描述信息
  • modifier : Modifier:Image 的修饰符
  • aligment : Aligment:对齐方式
  • contentScale : ContentScale:图片的显示模式(ContentScale.Crop 居中裁剪)
  • alpha : Float:设置透明度,默认是 1.0f
  • colorFilter : ColorFilter:可以设置颜色滤镜

引入 coil 依赖库加载网络图片

1
2
3
// build.gradle
implementation "io.coil-kt:coil:1.4.0"
implementation "io.coil-kt:coil-compose:1.4.0"

coil 是 Compose 中推荐使用的图片网络加载库,底层采用 Kotlin 协程进行加载。添加了依赖之后,就可以使用 rememberImagePainter 直接将图片链接传给 data 即可。如下代码:

1
2
3
4
5
6
7
8
Image(
painter = rememberImagePainter(
data = "https://www.baidu.com/img/flexible/logo/pc/result.png"
),
contentDescription = "baidu",
modifier = Modifier.size(50.dp),
contentScale = ContentScale.Crop // 居中裁剪
)

Spacer组件

源码

1
2
3
fun Spacer(modifier: Modifier) {
...
}

示例

传统布局中,可以添加Margin属性,设置间距,在Jetpack Compose 中,可以使用Spacer() 来设置垂直和水平间距

1
2
3
4
Row {
Spacer(Modifier.width(20.dp))//设置水平间距20dp
Spacer(Modifier.height(20.dp)) //设置垂直间距20dp
}

Divider

源码

1
2
3
4
5
6
7
8
9
@Composable
fun Divider(
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.onSurface.copy(alpha = DividerAlpha),
thickness: Dp = 1.dp,
startIndent: Dp = 0.dp
) {
...
}

属性

  • color //颜色
  • thickness //线的高度
  • startIndent //距离开始的间距

Surface

源码

1
2
3
4
5
6
7
8
9
10
11
12
@Composable
fun Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(color),
border: BorderStroke? = null,
elevation: Dp = 0.dp,
content: @Composable () -> Unit
) {
...
}

属性

当想要为我们自定义的一个组件添加背景颜色时,我们就需要用到 Surface,它主要有以下属性:

  • modifier: Modifier:可以为 Surface 设置修饰符
  • shape: Shape:设置形状,默认是 RectangleShape
  • color: Color:设置背景色
  • contentColor: Color:为 Surface 中的 Text 文字设置颜色,当 Text 没有指定颜色时,就是使用该颜色
  • border: Border?:设置外边框
  • elevation: Dp:为 Surface 设置在 Z 轴方向上的高度
  • content: @Composable () -> Unit:为 Surface 设置内容布局,需要传入 @Compose 方法

示例

1
2
3
4
5
6
7
8
9
10
Surface(modifier = Modifier.padding(4.dp), color = Color.Gray) {
Column {
Text(modifier = Modifier.align(Alignment.CenterHorizontally), text = "custom")
Image(
modifier = Modifier.size(150.dp),
painter = ColorPainter(color = Color.Green),
contentDescription = "image color"
)
}
}

Canvas

Canvas 是在屏幕上指定区域执行绘制的组件。注意在使用时需要添加修饰符来指定尺寸,可以通过 Modifier.size
设置固定的大小,也可以使用 Modifier.fillMaxSize,ColumnScope.weight 设置相对父组件大小。如果父组件没有设置大小,那么 Canvas
必须要设置固定的大小。
Canvas 就是类似于原来的自定义 View,但是更加的简便,通过 DrawScope 定义的绘制方法进行绘制出自己想要的效果,可以通过 drawArc ,drawCircle
,drawLine,drawPoints 等方法来绘制图形(详情可参考 DrawScope 下的方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width
val canvasHeight = size.height
// 绘制一条从左下角到右上角的蓝色的线
drawLine(
start = Offset(x = canvasWidth, y = 0f),
end = Offset(x = 0f, y = canvasHeight),
color = Color.Blue
)

// 在以 200,1200 位置 120 为半径绘制一个圆
drawCircle(color = Color.Green, center = Offset(200f, 1200f), radius = 120f)
}

滚动布局

只需要用 Column 中的 Modifier.verticalScroll 属性就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Composable
fun SimpleList() {
//使用 rememberScrollState 保存滚动的位置信息
val scrollState = rememberScrollState()
//Modifier.verticalScroll 可添加竖直方向上的滚动属性,使用 Column 的 Modifier.verticalScroll 方法确实可以创建一个可滑动的List,但是这种方法在开始时就会将所有 item 全部加载,类似于 ScrollView
Column(Modifier.verticalScroll(scrollState)) {
repeat(100) {
Text(text = "Item $it")
Divider(color = Color.Blue, thickness = 1.5.dp, startIndent = 10.dp)
}
}
}

@Composable
fun BodyContent(modifier: Modifier) {
Column(modifier = modifier) {
Text(text = "Hi there!")
Text(text = "Thanks for watching this")
SimpleList() // 将 List 放在之前的布局中展示出来
}
}

这种实现方法最简单,但是会在页面开始展示时,将列表中所有的 item 加载到内存中,虽然很多 item 都没有显示在屏幕上,这种方法当列表内容很多时,会出现内存占用大的问题。

列表

可以滾動的佈局

1
2
3
4
5
6
7
//我們可以使用 verticalScroll() 修飾符使 Column 可滾動
Column (
modifier = Modifier.verticalScroll(rememberScrollState())){
messages.forEach { message ->
MessageRow(message)
}
}

但以上佈局並無法實現重用,可能導致性能問題,下面介紹我們重點佈局,列表LazyColumn/LazyRow==RecylerView/listView列表佈局,解決了滾動時的性能問題,LazyColumn 和 LazyRow 之間的區別就在於它們的列表項佈局和滾動方向不同
內邊距:

1
2
3
4
5
6
LazyColumn(
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
) {
// ...
}

item間距:

1
2
3
4
5
LazyColumn(
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
// ...
}

浮動列表的浮動標題,使用 LazyColumn 實現粘性標題,可以使用實驗性 stickyHeader()函數

1
2
3
4
5
6
7
8
9
10
11
12
13
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ListWithHeader(items: List<Item>) {
LazyColumn {
stickyHeader {
Header()
}

items(items) { item ->
ItemRow(item)
}
}
}

網格佈局LazyVerticalGrid

1
2
3
4
5
6
7
8
9
10
11
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun PhotoGrid(photos: List<Photo>) {
LazyVerticalGrid(
cells = GridCells.Adaptive(minSize = 128.dp)
) {
items(photos) { photo ->
PhotoItem(photo)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Composable
fun CreateDrawerLayout() {
val list = mutableListOf<Student>()
for (i in 0..33) {
list.add(Student("学生${i}", i))
}
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(list.size) {
Text(
text = "items:姓名:${list[it].name},年龄${list[it].age}岁",
fontSize = 18.sp
)
Spacer(modifier = Modifier.height(10.dp))
}

itemsIndexed(items = list) { index: Int, item: Student ->
Text(
text = "itemsIndexed:姓名:${item.name},年龄${item.age}岁",
fontSize = 18.sp, modifier = Modifier.clickable {

})
Spacer(modifier = Modifier.height(10.dp))
}

list.forEachIndexed { index, student ->
item {
Text(
text = "forEachIndexed:姓名:${student.name},年龄${student.age}岁",
fontSize = 18.sp
)
Spacer(modifier = Modifier.height(10.dp))
}
}

}
}

data class Student(
val name: String,
val age: Int
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Composable
fun ImageListItem(index: Int) {
//列表 item 布局
//Row 可设置竖直方向上的对齐方式
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
painter = rememberImagePainter(
data = "https://pic.ntimg.cn/20140810/3822951_180850680000_2.jpg"
),
contentDescription = "Test Img",
modifier = Modifier.size(50.dp)
)
Spacer(modifier = Modifier.width(10.dp)) // Spacer 也可设置边距
Text(text = "Item #$index", style = MaterialTheme.typography.subtitle1)
}
}

@Composable
fun ScrollingList() {
val listSize = 100
// 使用 rememberLazyListState 保存滚动的位置
val scrollState = rememberLazyListState()

LazyColumn(state = scrollState) {
items(listSize) {
ImageListItem(index = it)
Divider(color = Color.Blue, thickness = 1.5.dp, startIndent = 10.dp)
}
}
}

Scaffold

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Scaffold(
modifier: Modifier = Modifier,
scaffoldState: ScaffoldState = rememberScaffoldState(),
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
isFloatingActionButtonDocked: Boolean = false,
drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
drawerGesturesEnabled: Boolean = true,
drawerShape: Shape = MaterialTheme.shapes.large,
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
drawerScrimColor: Color = DrawerDefaults.scrimColor,
backgroundColor: Color = MaterialTheme.colors.background,
contentColor: Color = contentColorFor(backgroundColor),
content: @Composable (PaddingValues) -> Unit
)

属性说明

  • topBar 顶部的布局
  • bottomBar 底部的布局
  • floatingActionButton 悬浮按钮布局
  • floatingActionButtonPosition 悬浮按钮位置,有FabPosition.End(默认)和FabPosition.Center可选
  • isFloatingActionButtonDocked 与BottomAppBar配合使用,可以实现底部导航条的裁剪效果,效果可以看下图
  • drawerGesturesEnabled 是否开启侧边抽屉手势(开启后可侧滑弹出抽屉)
  • drawerShape 抽屉的形状
  • drawerContent 侧边抽屉内容,是个Column布局,自己可以顺便排列
  • drawerElevation 侧边抽屉的阴影
  • drawerBackgroundColor 侧边抽屉的背景色
  • drawerContentColor 侧边抽屉内容颜色(似乎是覆盖字体颜色而已)
  • drawerScrimColor 侧边抽屉遮盖最底层的颜色

Material 支持的最高级别的可组合项是 Scaffold。Scaffold 可让您实现具有基本 Material Design 布局结构的界面。Scaffold 可以为最常见的顶级 Material 组件(如 TopAppBar、BottomAppBar、FloatingActionButton 和 Drawer)提供插槽。通过使用 Scaffold,很容易确保这些组件得到适当放置且正确地协同工作。

BottomNavigation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@Composable
fun Tab(viewModel: ViewMod){
// tab标题
val listItem = listOf("组织","发现","我的")
// tab未选图标
val icons = listOf(R.drawable.home,R.drawable.find,R.drawable.profile)
// tab选中图标
val selectIcons = listOf(R.drawable.homeselect,R.drawable.findselect,R.drawable.profileselect)
// 记住选中tab位置
val selectIndex = remember {
mutableStateOf(0)
}
// 脚手架
val navControllers = rememberNavController()
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
// BottomNavigation的显示和隐藏先借助本地数据存储,再说
BottomNavigation(
backgroundColor = Color.White,
elevation = 3.dp
) {
val navBackStackEntry by navControllers.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)

items.forEachIndexed { index, s ->
BottomNavigationItem(
selected = currentRoute == s.route,
onClick = {
selectIndex.value = index
navControllers.navigate(s.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
popUpTo = navControllers.graph.startDestination
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
}
},
icon = {
when(index){
selectIndex.value -> {
Image(painter = painterResource(id = selectIcons[index]), contentDescription = null)
}
else -> {
Image(painter = painterResource(id = icons[index]), contentDescription = null)
}
}
},
label = {
Text(
text = listItem[index],
textAlign = TextAlign.Center,
color = if (index == selectIndex.value) Color(0xFF0077E6) else Color(0xFFD8D8D8)
)
}
)
}
}
},
content = {
NavHost(navControllers, startDestination = Screen.Home.route) {
// 首页
composable(Screen.Home.route) { Home(viewModel,navControllers) }
// 发现
composable(Screen.Find.route) { Find(navControllers) }
// 我的
composable(Screen.Profile.route) { Profile(navControllers,viewModel) }
}
}
)
}

sealed class Screen(val route: String, @StringRes val resourceId: Int) {
object Home : Screen("home", R.string.home)
object Find : Screen("find", R.string.find)
object Profile : Screen("profile", R.string.profile)

}

val items = listOf(
Screen.Home,
Screen.Find,
Screen.Profile
)

OutlinedTextField 属性解析

在实现以上效果前,先要了解OutlinedTextField的属性,才能加以运用 ;先看一下属性列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Composable
fun OutlinedTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
readOnly: Boolean = false,
textStyle: TextStyle = LocalTextStyle.current,
label: @Composable (() -> Unit)? = null,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
isError: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = MaterialTheme.shapes.small,
colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()
)
  • value: String 输入框显示的文本
  • onValueChange: (String) -> Unit 值发生改变之后触发的回调
  • modifier: Modifier = Modifier 修饰
  • enabled: Boolean = true 可用
  • readOnly: Boolean = false 是否只读
  • textStyle: TextStyle = LocalTextStyle.current
  • label: @Composable (() -> Unit)? = null 输入框获取焦点时左上角提示的内容
  • placeholder: @Composable (() -> Unit)? = null 输入框提示的内容
  • leadingIcon: @Composable (() -> Unit)? = null 输入框左侧的图标
  • trailingIcon: @Composable (() -> Unit)? = null 输入框右侧的图标
  • isError: Boolean = false 是否处于错误状态
  • visualTransformation: VisualTransformation = VisualTransformation.None, 转换输入值的视觉表示
  • keyboardOptions: KeyboardOptions = KeyboardOptions.Default 输入框输入类型
  • singleLine: Boolean = false, 是否单行显示
  • maxLines: Int = Int.MAX_VALUE 最大行数
  • colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors() 颜色集合,设置获取焦点,失去焦点以及光标等颜色

AlertDialog

1、属性一览
【目前基于alpha09版本】请看该对话框支持的两个函数,首先看第一个函数,该函数会根据可用空间水平放置其按钮:

1
2
3
4
5
6
7
8
9
10
11
12
@Composable fun AlertDialog(
onDismissRequest: () -> Unit,
confirmButton: () -> Unit,
modifier: Modifier = Modifier,
dismissButton: () -> Unit = null,
title: () -> Unit = null,
text: () -> Unit = null,
shape: Shape = MaterialTheme.shapes.medium,
backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(backgroundColor),
properties: DialogProperties? = null
): Unit
  • modifier: Modifier = Modifier 应用于布局的修饰符
  • onDismissRequest: () -> Unit 当用户点击对话框外部或者按下返回按钮的时候会执行。注意:点击对话框的关闭按钮时并不会执行
  • confirmButton: () -> Unit 一个由用户确认操作的按钮,默认没有回调,需要调用者自行设置回调事件。
  • dismissButton: () -> Unit = null 一个用于关闭对话框的按钮,默认没有回调,需要调用者自行设置回调事件。
  • title: () -> Unit = null 对话框的标题,默认无
  • text: () -> Unit = null 对话框的内容,默认无
  • shape: Shape = MaterialTheme.shapes.medium 对话框的形状
  • backgroundColor: Color = MaterialTheme.colors.surface 对话框的背景色
  • contentColor: Color = contentColorFor(backgroundColor) 提供给其子级的首选内容颜色
  • properties: DialogProperties? = null 用于进一步配置特定属性的对话框

Tab及ScrollableTabRow

关于tab有两个函数,如下:

1
2
3
4
5
6
7
8
9
10
@Composable fun Tab(
selected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: () -> Unit = emptyContent(),
icon: () -> Unit = emptyContent(),
interactionState: InteractionState = remember { InteractionState() },
selectedContentColor: Color = AmbientContentColor.current,
unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
): Unit
  • selected: Boolean 该Tab是否被选中
  • onClick: () -> Unit 点击该Tab时候的回调事件
  • modifier: Modifier = Modifier 应用于该Tab的修饰符
  • text: () -> Unit = emptyContent() 显示在该Tab中的文本
  • icon: () -> Unit = emptyContent() 显示在该Tab中的图标
  • interactionState: InteractionState = remember { InteractionState() } 该Tab的交互状态
  • selectedContentColor: Color = AmbientContentColor.current 选中该Tab时内容的颜色,以及水波纹的颜色
  • unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium) 未选中该Tab时内容的颜色

参考资料:
Jetpack Compose初体验
compose资料
Compose UI官方文档
Android全新UI编程 - Jetpack Compose 超详细教程
JetPack Compose 之 state
Jetpack-Compose 学习笔记
Jetpack-Compose
Compose的State(九)
Compose系列 三 状态管理
原创|Android Jetpack Compose 最全上手指南
Android Jetpack Compose 超快速上手指南
compose text组件
Jetpack Compose初体验–(布局、动画等)
Jetpack Compose初体验–(导航、生命周期等)
compose text组件
Jetpack Compose初体验–(布局、动画等)
Jetpack Compose初体验–(导航、生命周期等)

告别XML,使用Compose Theme为你的app轻松换皮