4、Jetpack Compose 入门 --- 布局

456 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 4 天,点击查看活动详情

Compose的布局系统,大致可以分为两类:

  • 标准布局组件:ColumnRowBox
  • 基于槽位的布局:Scaffold

标准布局组件

Compose提供了三个标准布局组件,分别是ColumnRowBox

标准布局组件描述
Column垂直方向布局
Row水平方向布局
Box层叠布局

image.png

Column

inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
)
参数类型描述可选值
modifierModifier修饰符
verticalArrangementVertical子组件的垂直安排Top:子组件挨着放在顶部
Bottom:子组件挨着放在底部
Center:子组件挨着放在中间
SpaceEvenly:第一个子组件之前与最后一个子组件之后及相邻子组件之间完全均分空间
SpaceBetween:相邻子组件之间均分空间,第一个子组件之前与最后一个子组件之后不分配空间
SpaceAround:相邻子组件之间均分空间,第一个子组件之前与最后一个子组件之后分配的控件减半
horizontalAlignmentAlignment.Horizontal水平方向对齐方式Alignment.Start:靠在起始位置
Alignment.End:靠在结束位置
Alignment.CenterHorizontally:居中
content@Composable ColumnScope.() -> Unit内容

verticalArrangement

image.png image.png image.png image.png image.png image.png

horizontalAlignment

image.png image.png image.png

Row

inline fun Row(
    modifier: Modifier = Modifier,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    content: @Composable RowScope.() -> Unit
)
参数类型描述可选值
modifierModifier修饰符
horizontalArrangementHorizontal子组件的水平安排Start:子组件挨着放在开始位置
End:子组件挨着放在结束位置
Center:子组件挨着放在中间
SpaceEvenly:第一个子组件之前与最后一个子组件之后及相邻子组件之间完全均分空间
SpaceBetween:相邻子组件之间均分空间,第一个子组件之前与最后一个子组件之后不分配空间
SpaceAround:相邻子组件之间均分空间,第一个子组件之前与最后一个子组件之后分配的控件减半
verticalAlignmentAlignment.Vertical垂直方向对齐方式Alignment.Top:靠在顶部
Alignment.Bottom:靠在底部
Alignment.CenterVertically:居中
content@Composable RowScope.() -> Unit内容

horizontalArrangement

image.png image.png image.png image.png image.png image.png

verticalAlignment

image.png image.png image.png

Box

inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
)
参数类型描述可选值
contentAlignmentAlignment内容的对齐方式Alignment.TopStart
Alignment.TopCenter
Alignment.TopEnd
Alignment.CenterStart
Alignment.Center
Alignment.CenterEnd
Alignment.BottomStart
Alignment.BottomCenter
Alignment.BottomEnd
propagateMinConstraintsBoolean是否将最小约束传递给子内容

contentAlignment

image.png

propagateMinConstraints

image.png

Box(
    modifier = Modifier
        .padding(4.dp)
        .sizeIn(minWidth = 150.dp, minHeight = 150.dp),
    propagateMinConstraints = true
) {
    Box(
        modifier = Modifier
            .size(200.dp)
            .background(color = Color.LightGray)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(color = Color.Red)
    )
}

image.png

Box(
    modifier = Modifier
        .padding(4.dp)
        .sizeIn(minWidth = 150.dp, minHeight = 150.dp),
    propagateMinConstraints = falses
) {
    Box(
        modifier = Modifier
            .size(200.dp)
            .background(color = Color.LightGray)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(color = Color.Red)
    )
}

基于槽位的布局

先看看上图的效果:

  • 主界面分为上(TopBar)、中(Content)、下(BottomBar)三部分
  • 主界面右下角有一个悬浮按钮(F)
  • 主界面左侧有一个抽屉
  • 抽屉在打开的过程中,主界面上层有一个颜色的渐变过程

GIF 2022-4-10 15-40-23.gif

要实现这样一个效果,只需要使用Compose的Scaffold组件就可以十分简单地实现,代码如下:

Scaffold(
    topBar = {
        BoxText(
            text = "TopBar",
            modifier = Modifier
                .fillMaxWidth()
                .height(48.dp)
                .background(color = Color.Red),
            contentAlignment = Alignment.Center
        )
    },
    bottomBar = {
        BoxText(
            text = "BottomBar",
            modifier = Modifier
                .fillMaxWidth()
                .height(48.dp)
                .background(color = Color.Blue),
            contentAlignment = Alignment.Center
        )
    },
    floatingActionButton = {
        Button(onClick = { }) { Text(text = "F") }
    },
    drawerContent = {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(color = Color.Gray),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "Text1")
            Text(text = "Text2")
        }
    },
    drawerScrimColor = Color.LightGray
) {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Content")
    }
}

Scaffold

接下来看看Scaffold的参数:

@Composable
fun 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
)
参数类型描述可选值(说明)
modifierModifier修饰符
scaffoldStateScaffoldStateScaffold组件的状态包含两个属性:
drawerState:抽屉状态
snackbarHostState:Snackbar状态
topBar@Composable () -> Unit顶部栏推荐使用TopAppBar
bottomBar@Composable () -> Unit底部条推荐使用BottomAppBar
snackbarHost@Composable (SnackbarHostState) -> UnitSnackbar推荐使用snackbarhost
floatingActionButton@Composable () -> Unit屏幕的悬浮按钮推荐使用FloatingActionButton
floatingActionButtonPositionFabPosition悬浮按钮的位置Center:底部中间
End:底部结束位置
isFloatingActionButtonDockedBoolean如果存在bottomBar,悬浮按钮是否与bottomBar的顶部重合一半的高度
drawerContent@Composable (ColumnScope.() -> Unit)?抽屉内容从屏幕的左侧弹出
drawerGesturesEnabledBoolean抽屉是否支持通过手势互动如果为true,则可以通过手势滑动打开或关闭抽屉
drawerShapeShape抽屉的外形
drawerElevationDp抽屉的高度这决定了抽屉下方的阴影尺寸
drawerBackgroundColorColor抽屉的背景颜色
drawerContentColorColor抽屉内容的颜色
drawerScrimColorColor抽屉打开时,未覆盖主界面部分的背景颜色在抽屉打开的过程中,背景颜色有渐变过程
backgroundColorColor主体内容的背景颜色
contentColorColor主体内容的颜色
content@Composable (PaddingValues) -> Unit主体内容