持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
概述
本篇学习笔记主要是学习Appbar
组件的使用,在Compose
中我们一般使用Scaffold
作为页面的根可组合项,Scaffold
为我们提供了很多的属性来进行一些自定义的操作,其中AppBar
组件就是方面我们实现页面的顶部或者底部导航来提供的。
简单使用
下面的代码中指定了使用TopAppBar
和BottomAppBar
,没有定义任何的属性,如下代码所示:
Scaffold(modifier = Modifier.fillMaxSize(), topBar = {
TopAppBar() {
}
}, bottomBar = {
BottomAppBar() {
}
}) {
SimpleTextContent(content = LocalContext.current.getString(R.string.app_bar)) {
}
}
直接运行上面的代码就可以看到如下的效果:
可以看到,不管是AppTopBar
还是AppBottomBar
,本身是带有高度的,同时本身也是宽度扩展到全屏的,我们不需要指定它们的宽度和高度。
backgroundColor
如果我们需要设置AppBar
的背景颜色,那么应该通过其自身的backgroundColor
属性去设置,虽然AppBar
也可以接收Modifier
相关的参数,但是如果我们通过Modifier.background()
去设置背景颜色的话,那么将无法看到任何效果。
TopAppBar(backgroundColor = Color.Black) {
}
设置标题title
我们可以给AppBar
通过title
参数指定一个标题,从方法的定义上看,title
可以接收一个可组合项,因此我们设置的标题将没有限制,如下面的代码所示:
TopAppBar(
backgroundColor = Color.Blue,
title = {
Text(text = "这里是页面的标题",color = Color.White)
},
)
在上面的代码中我们就仅仅是指定了一个Text
来作为标题,一般来说我们也只需要一个Text
即可。
需要注意的是,如果我们想要标题居中显示的话,我们可以通过下面两种方式去指定:
- 通过给
Text
设置Modifier.fillMaxWidth()
配合textAlign = TextAlign.Center
可是显示标题居中的效果,这种效果标题只能在宽度上铺满父可组合项,高度上则是根据文字的高度自行设置的。 - 通过给
Text
设置Modifier.fillMaxSize()
配合wrapContentSize(align = Alignment.Center)
可以达到Text
在宽度和高度均占满父可组合项并且标题是居中的。
设置导航按钮
一般情况下,如果不是在应用的首页,我们可能会给标题栏上添加一个返回按钮,这样方便用户在目的地之间导航,在TopAppBar
中,我们可以向其传递navigationIcon
字段的值,并设置一个可组合项作为导航按钮,可组合项可以任意设置,并不一定非得是返回按钮,下面的代码设置返回按钮作为导航按钮,点击之后可以退出当前可组合项,返回到之前的可组合项:
navigationIcon = {
IconButton(onClick = { controller.popBackStack() }) {
Image(
painter = painterResource(id = R.drawable.ic_back_white),
contentDescription = "返回"
)
}
}
设置上面的属性就可以设置导航,其中controller
是导航组件提供的NavController
,不熟悉这里的可以查看官方文档中导航组件部分。
需要注意的是:如果我们的导航图标通过Icon
去设置的话,在设置了TopAppBar
的背景颜色的情况下,Icon
的图标颜色可能无法正确显示,我们需要指定其tint
属性配置它的颜色才能正确显示,如下所示:
IconButton(onClick = { controller.popBackStack() }) {
Icon(
painter = painterResource(id = R.drawable.ic_back_white),
contentDescription = "返回",
tint = Color.White
)
}
下面是设置了导航组件的效果:
设置操作列表
除了导航按钮,有时候我们也需要给标题栏设置一些常用的操作,用户可以通过设置的这些按钮执行一些快捷操作,在TopAppBar
中我们可以通过向actions
参数传递可组合项达到这样的效果。
下面的代码演示了在TopAppBar
上添加相应的操作按钮:
actions = {
Icon(
painter = painterResource(id = R.drawable.ic_menu_white_24),
contentDescription = "菜单",
)
Icon(painterResource(id = R.drawable.ic_search_white_24), contentDescription = "搜索",)
Icon(
painter = painterResource(id = R.drawable.ic_history_white_24),
contentDescription = "历史",
)
}
在上面的代码中我们添加了三个操作按钮,由于这里只是为了演示,所以就只设置了Icon
,如果需要在点击之后执行相应的操作,可以设置其父组合项为Button
即可。
另外需要注意的一点是:actions里面的可组合项是使用Row
的方式排列的,这里源码中对actions
的定义为actions: @Composable RowScope.() -> Unit = {}
,也就是说我们在可组合项中可以使用RowScope
的相关属性,比如weight
,但是问题是在设置了weight
属性后,之前设置的title
可组合项就不可见了。
下面是设置操作列表的效果:
设置内容颜色
在设置导航按钮的时候,我们发现,不指定Icon
的tint
属性,最终显示的图标颜色会有问题,但是在设置actions
的时候,我们并没有指定tint
属性,最终的效果也是没有问题的,这是因为我们同时设置了contentColor
属性。
源码中contentColor
的默认值为contentColor: Color = contentColorFor(backgroundColor)
,这是根据我们设置的背景颜色到主题中去匹配一个与之对应的颜色,之前我们没有设置contentColor
,只设置了backgroundColor
,而匹配上的颜色和我们想要的颜色(图标本身的颜色)不一样,所以会造成显示效果上的差异。
下面的代码指定了内容的颜色为白色:
contentColor = Color.White
设置Z轴高度
为了能够明显区分屏幕中标题栏和其它部分,有时候我们需要给标题栏设置一个突起(Z轴的高度),TopAppBar
向我们提供了elevation
属性来设置阴影效果,如下面的代码所示:
elevation = 10.dp
实际上在之前的代码演示中,我们就已经能够看到设置了Z轴高度的效果,因为默认TopAppBar
就会设置期高度,相应的代码如下:
elevation: Dp = AppBarDefaults.TopAppBarElevation
val TopAppBarElevation = 4.dp
可以看到,默认的Z轴高度是4dp.
至此,TopAppBar
的相关内容就学习完了,可以看到,TopAppBar
的使用还是很简单的,我们只需要向其中传递必要的参数即可快速实现一个通用的标题栏。
BottomAppBar
在Scaffold
可组合项中,除了提供了topBar
的配置,也提供了bottomBar
的配置,一般情况下,我们可以使用BottomAppBar
来创建底部的标题栏,不过底部标题栏在具体的项目中使用的不多,因此这里的可配置项并不是很多,下面的代码演示了BottomAppBar
的基本使用:
bottomBar = {
BottomAppBar(
backgroundColor = Color.Red,
contentColor = Color.White,
elevation = 6.dp,
contentPadding = PaddingValues(start = 50.dp, end = 50.dp),
cutoutShape = MaterialTheme.shapes.small.copy(CornerSize(50.dp))
) {
Text(text = "这里是底部操作栏")
}
}
这里需要注意的是:cutoutShape
用于在Scaffold
中设置FloatingActionButton
的时候,为了和这个可组合项配合需要使用的切口形状,这里可以接收一个Shape
类型的参数,也就是说我们可以接收任意的缺口形状。除此之外,BottomAppBar
的其他参数的含义和TopAppBar
相同。
下面是使用BottonAppBar
的效果: