如何在 Jetpack Compose 中实现这种布局

ale*_*rdi 11 android android-layout android-jetpack-compose

我正在尝试使用新的 Jetpack Compose UI 框架,但遇到了问题。我想实现这个布局,在 xml 中很容易实现:

正确布局

但我无法弄清楚如何使垂直分隔线占用可用的垂直空间,而不指定固定的高度。我尝试过的这段代码似乎不起作用:

@Composable
fun ListItem(item: PlateUI.Plate) {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(8.dp),
        elevation = 2.dp
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(
                modifier = Modifier
                    .padding(8.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(text = "Code")
                Text(text = item.code)
            }
            Spacer(
                modifier = Modifier
                    .preferredWidth(1.dp)
                    .background(color = MaterialTheme.colors.onSurface.copy(0.12f))
            )
            Spacer(modifier = Modifier.weight(1f))
            Text(
                modifier = Modifier
                    .padding(horizontal = 8.dp, vertical = 34.dp),
                text = item.name
            )
            Spacer(modifier = Modifier.weight(1f))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不断得到这个结果:

在此输入图像描述

我也尝试过使用 ConstraintLayout,但它仍然不起作用

@Composable
fun ListItem(item: PlateUI.Plate) {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(8.dp),
        elevation = 2.dp
    ) {
        ConstraintLayout(
            modifier = Modifier.fillMaxWidth(),
        ) {
            val(column, divider, text) = createRefs()
            Column(
                modifier = Modifier
                    .padding(8.dp)
                    .constrainAs(column){
                        top.linkTo(parent.top)
                        bottom.linkTo(parent.bottom)
                        start.linkTo(parent.start)
                    },
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(text = "Code")
                Text(text = item.code)
            }
            Spacer(
                modifier = Modifier
                    .preferredWidth(1.dp)
                    .background(color = MaterialTheme.colors.onSurface.copy(0.12f))
                    .constrainAs(divider){
                        top.linkTo(parent.top)
                        bottom.linkTo(parent.bottom)
                        start.linkTo(column.end)
                    }
            )
            Text(
                modifier = Modifier
                    .padding(horizontal = 8.dp, vertical = 34.dp)
                    .constrainAs(text){
                        start.linkTo(divider.end)
                        end.linkTo(parent.end)
                        top.linkTo(parent.top)
                        bottom.linkTo(parent.bottom)
                    },
                text = item.name
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但似乎没有任何作用。这是一个错误、一个缺失的功能还是我只是错过了一些东西?

编辑:显然真正的问题是,当 Surface 没有固定高度时,分隔线不知道如何测量,将高度设置为等于某个数字可以解决问题,但视图不会适应内容高度不再了,所以这不是解决方案

Gab*_*tti 11

您可以申请:

  • .height(IntrinsicSize.Max)的修饰符Row
  • .width(1.dp).fillMaxHeight()的修饰符Spacer

您可以在此处阅读有关本征测量 的更多信息。

就像是:

Row(
    modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
    verticalAlignment = Alignment.CenterVertically
) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        ....
    ) {
        Text(text = "....")
    }
    Spacer(
        modifier = Modifier
            .width(1.dp)
            .fillMaxHeight()
            .background(color = MaterialTheme.colors.onSurface.copy(0.12f))
    )
    Text(...)
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 嗯...不。这样该行就不会具有动态高度,我希望它能够适应多行文本和其他高度变化 (2认同)

Mik*_*ell 4

您可以设置的Intrinsic.Max,然后设置填充最大高度。您可以在此 Codelab 部分中阅读有关 s的更多信息。preferredHeightRowSpacerIntrinsic

@Composable
fun ListItem() {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(8.dp),
        elevation = 2.dp
    ) {
        Row(
            modifier = Modifier.fillMaxWidth().preferredHeight(IntrinsicSize.Max),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(
                modifier = Modifier
                    .padding(8.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(text = "Code")
                Text(text = "2456")
            }
            Spacer(
                modifier = Modifier
                    .preferredWidth(1.dp)
                    .fillMaxHeight()
                    .background(color = Color.Black.copy(0.12f))
            )
            Spacer(modifier = Modifier.weight(1f))
            Text(
                modifier = Modifier
                    .padding(horizontal = 8.dp, vertical = 34.dp),
                text = "Some name"
            )
            Spacer(modifier = Modifier.weight(1f))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)