如何在 Jetpack Compose 中对齐到底部行?

Pau*_*999 33 android kotlin android-jetpack-compose android-jetpack-compose-layout

我有一个包含一些行的列,我想在底部对齐最后一行,但该行永远不会位于屏幕底部,它位于上一行之后:

    Column {
        // RED BOX
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(130.dp)                
                .padding(vertical = 15.dp, horizontal = 30.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column {
                Text(
                    text = stringResource(id = R.string.app_name),
                    style = TextStyle(fontSize = 40.sp),
                    color = Color.White
                )
                Text(
                    text = stringResource(id = R.string.app_description),
                    style = TextStyle(fontSize = 13.sp),
                    fontWeight = FontWeight.Bold,
                    color = Color.Black
                )
            }
        }

        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .height(15.dp)
        )

        // GREEN BOX
        val currentRoute = currentRoute(navController)
        items.forEach { item ->
            DrawerItem(item = item, selected = currentRoute == item.route) {
                navController.navigate(item.route) {
                    launchSingleTop = true
                }

                scope.launch {
                    scaffoldState.drawerState.close()
                }
            }
        }

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(vertical = 15.dp, horizontal = 30.dp),
            verticalAlignment = Alignment.Bottom,
            horizontalArrangement = Arrangement.Center
        ) {
            Text(
                text = BuildConfig.VERSION_NAME,
                style = TextStyle(fontSize = 11.sp),
                color = Color.Black,
            )
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想要得到与图片中所示相同的东西。我想要第一行(红色),然后是第二行(绿色),然后是适合屏幕底部的第三行(蓝色)

在此输入图像描述

Thr*_*ian 41

您可以使用Spacer(modifier.weight(1f))GreenBox 和 Blue Box 之间的 来在它们之间创建空间,或者您可以使用函数创建自定义列Layout并将最后一个的 y 位置设置PlaceableComposable - 最后一个的高度Composble

    Column(modifier = Modifier
        .fillMaxHeight()
        .background(Color.LightGray)) {
        Text(
            "First Text",
            modifier = Modifier
                .background(Color(0xffF44336)),
            color = Color.White
        )
        Text(
            "Second Text",
            modifier = Modifier
                .background(Color(0xff9C27B0)),
            color = Color.White
        )
        Spacer(modifier = Modifier.weight(1f))
        Text(
            "Third Text",
            modifier = Modifier
                .background(Color(0xff2196F3)),
            color = Color.White
        )
    }
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

自定义布局

@Composable
private fun CustomColumn(
    modifier: Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->

        val looseConstraints = constraints.copy(
            minWidth = 0,
            maxWidth = constraints.maxWidth,
            minHeight = 0,
            maxHeight = constraints.maxHeight
        )

        // Don't constrain child views further, measure them with given constraints
        // List of measured children
        val placeables = measurables.map { measurable ->
            // Measure each child
            measurable.measure(looseConstraints)
        }

        // Track the y co-ord we have placed children up to
        var yPosition = 0


        // Set the size of the layout as big as it can
        layout(constraints.maxWidth, constraints.maxHeight) {
            // Place children in the parent layout
            placeables.forEachIndexed { index, placeable ->

                println("Placeable width: ${placeable.width}, measuredWidth: ${placeable.measuredWidth}")
                // Position item on the screen
                if (index == placeables.size - 1) {
                    placeable.placeRelative(x = 0, y = constraints.maxHeight - placeable.height)
                } else {
                    placeable.placeRelative(x = 0, y = yPosition)
                }

                // Record the y co-ord placed up to
                yPosition += placeable.height
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

    CustomColumn(
        modifier = Modifier
            .fillMaxHeight()
            .background(Color.LightGray)
    ) {
        Text(
            "First Text",
            modifier = Modifier
                .background(Color(0xffF44336)),
            color = Color.White
        )
        Text(
            "Second Text",
            modifier = Modifier
                .background(Color(0xff9C27B0)),
            color = Color.White
        )
        Spacer(modifier = Modifier.weight(1f))
        Text(
            "Third Text",
            modifier = Modifier
                .background(Color(0xff2196F3)),
            color = Color.White
        )
    }
Run Code Online (Sandbox Code Playgroud)

结果: 在此输入图像描述

在这个布局示例中,您应该考虑如何使用约束以及总宽度和高度来测量可测量值。它需要一点练习,但与现成的设计相比,您可以获得更独特的设计,并且需要更少的工作(更优化)的可组合性。这里我将布局设置为 maxWidth,因此无论您分配哪个宽度,它都会占用整个宽度。用于演示,您可以layout根据需要设置最大宽度或高度。

  • 设置特定的视图高度似乎是一个非常糟糕的主意。 (2认同)

Gab*_*tti 36

您可以通过多种方式做到这一点。

您可以使用 Column 并将verticalArrangement = Arrangement.SpaceBetweena 分配weight(1f,false)给最后一行:

  Column(
     Modifier.fillMaxHeight(),
     verticalArrangement = Arrangement.SpaceBetween) {
     
     //All elements 
     Column {

        // RED BOX
        
        //...
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .background(Green)
                .height(15.dp)
        )

       //... Green box
    }

    //LAST ROW
    Row(
        modifier = Modifier
            .weight(1f, false)
    ) {
        //...
    }
 }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 如果我的内栏有“verticalScroll()”,它就不起作用,有什么方法可以在可滚动内容中实现类似的场景。 (2认同)

Aka*_*ash 5

这对我有用:

结构是这样的:

Column // arrangement = Arrangement.SpaceBetween
  Column
    Row 1
    Row 2
    Row 3
  Row 4
Run Code Online (Sandbox Code Playgroud)
@Preview(showSystemUi = true)
@Composable
fun AlignBottomExample() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.SpaceBetween
    ) {

        Column() {
            Row(
                modifier = Modifier.height(100.dp)
                    .background(Color.Magenta)
                    .fillMaxWidth(),
            ) {
                Text(text = "Row 1")
            }
            Row(
                modifier = Modifier.height(100.dp)
                    .background(Color.Cyan)
                    .fillMaxWidth(),
            ) {
                Text(text = "Row 2")
            }
            Row(
                modifier = Modifier.height(100.dp)
                    .background(Color.Yellow)
                    .fillMaxWidth(),
            ) {
                Text(text = "Row 3")
            }
        }

        Row(
            modifier = Modifier.height(100.dp)
                .background(Color.Green)
                .fillMaxWidth(),
        ) {
            Text(text = "Row 4")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述