ModalDrawer是Jetpack Compose提供的侧滑抽屉组件,它展开后位于应用程序的大部分UI之上。 抽屉始终由抽屉外部的启示组件打开,例如顶部应用栏中的导航菜单图标。 抽屉可以通过以下方式关闭: 1 选择了抽屉中的一个子项 2 点击屏幕空白 3 手势向起始侧边滑动
来看一下ModalDrawer的参数
@Composable
fun ModalDrawer(
//抽屉的布局
drawerContent: @Composable ColumnScope.() -> Unit,
modifier: Modifier = Modifier,
drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
//抽屉是否可以通过手势进行交互
gesturesEnabled: Boolean = true,
drawerShape: Shape = MaterialTheme.shapes.large,
//边框阴影
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
//抽屉展开后空白处的颜色
scrimColor: Color = DrawerDefaults.scrimColor,
//界面布局,收起抽屉后展示的UI
content: @Composable () -> Unit
): Unit
先来看一下demo的界面:
抽屉侧滑部分的布局: 包括一个头部和三个Item
/**
* 抽屉的布局
*/
@Composable
private fun DrawerContent(
modifier: Modifier = Modifier,
currenItemFlag:MutableState<DrawerItemFlag>,
closeDrawer: () -> Unit
){
Column(modifier = modifier.fillMaxSize()) {
DrawerHeader()
DrawerItem(
painter = painterResource(id = R.drawable.ic_baseline_lens_24),
label = stringResource(id = R.string.one),
isSelected = if(currenItemFlag.value == DrawerItemFlag.One) true else false,
onClick = {
closeDrawer()
currenItemFlag.value = DrawerItemFlag.One
}
)
DrawerItem(
painter = painterResource(id = R.drawable.ic_baseline_lens_24),
label = stringResource(id = R.string.two),
isSelected = if(currenItemFlag.value == DrawerItemFlag.Two) true else false,
onClick = {
closeDrawer()
currenItemFlag.value = DrawerItemFlag.Two
}
)
DrawerItem(
painter = painterResource(id = R.drawable.ic_baseline_lens_24),
label = stringResource(id = R.string.three),
isSelected = if(currenItemFlag.value == DrawerItemFlag.Three) true else false,
onClick = {
closeDrawer()
currenItemFlag.value = DrawerItemFlag.Three
}
)
}
}
抽屉头部布局: 一个简单的头像和文本标签布局
/**
* 抽屉布局中的头部布局
*/
@Composable
private fun DrawerHeader(
modifier: Modifier = Modifier
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = modifier
.fillMaxWidth()
.background(Color.Blue)
.height(dimensionResource(id = R.dimen.header_height))
.padding(dimensionResource(id = R.dimen.header_padding))
) {
Image(
painter = painterResource(id = R.drawable.ic_baseline_account_circle_24),
contentDescription =
stringResource(id = R.string.me),
modifier = Modifier.size(100.dp)
)
Text(
text = stringResource(id = R.string.me),
color = MaterialTheme.colors.surface
)
}
}
抽屉Item布局:
/**
* 抽屉的Item
*/
@Composable
private fun DrawerItem(
modifier: Modifier = Modifier,
label:String,
painter: Painter,
tintColor:Color = Color.DarkGray,
isSelected:Boolean = false,
onClick:() -> Unit
){
val color = if(isSelected) Color.Blue else tintColor
Row(
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.padding(10.dp)
.clickable { onClick() }
) {
Icon(
painter = painter,
contentDescription = null, // decorative
tint = color
)
Spacer(Modifier.width(16.dp))
Text(
text = label,
style = MaterialTheme.typography.body2,
color = color
)
}
}
完整的抽屉布局:
@OptIn(ExperimentalUnitApi::class)
@Composable
fun ModalDrawerDemo(drawerState: DrawerState) {
val scope = rememberCoroutineScope()
//当前抽屉被选中的Item
val currenItemFlag = remember {
mutableStateOf(DrawerItemFlag.One)
}
ModalDrawer(
drawerState = drawerState,
drawerShape = MaterialTheme.shapes.small,
drawerContent = {
DrawerContent(currenItemFlag = currenItemFlag) {
scope.launch { drawerState.close() }
}
},
content = {
//根据选择的draweritem切换不同的content
if(currenItemFlag.value == DrawerItemFlag.One) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Red)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = stringResource(id = R.string.one), fontSize = TextUnit(50f,
TextUnitType.Sp))
}
}else if (currenItemFlag.value == DrawerItemFlag.Two){
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Green)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = stringResource(id = R.string.two), fontSize = TextUnit(50f,
TextUnitType.Sp))
}
}else{
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = stringResource(id = R.string.three), fontSize = TextUnit(50f,
TextUnitType.Sp))
}
}
}
)
}