问题
I'm trying to use the new Jetpack Compose UI framework, but i'm running into an issue. I'd like to achieve this layout, wich in xml is pretty easy to achieve:
But i can't figure out hou to make the vertical divider take up the available vertical space, without specifying a fixed height. This code that I've tried doesn't seem to work:
@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))
}
}
}
I keep getting this result:
I also tried with ConstraintLayout, but it still didn't work
@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
)
}
}
}
But nothing seems to work. Is this a bug, a missing feature or am i just missing something?
EDIT: Apparently the real problem is that the divider doesn't know how to measure when the Surface doesn't have a fixed height, setting height equal to some number solves the issue, but then the view doesn't adapt to the content height anymore, so this can't be the solution
回答1:
You can use the Modifier.fillMaxHeight()
.
Something like:
Spacer(
modifier = Modifier
.preferredWidth(1.dp)
.fillMaxHeight()
.background(color = MaterialTheme.colors.onSurface.copy(0.12f))
)
回答2:
I've solved it using constraint layout:
Box(modifier = Modifier.padding(Dp(50f))) {
ConstraintLayout(
modifier = Modifier
.border(width = Dp(1f), color = Color.Black)
.fillMaxWidth()
) {
val (left, divider, right) = createRefs()
Column(
modifier = Modifier
.padding(horizontal = Dp(20f))
.constrainAs(left) {
width = Dimension.wrapContent
start.linkTo(parent.start)
top.linkTo(parent.top)
end.linkTo(divider.start)
bottom.linkTo(parent.bottom)
}
) {
Text(text = "Code")
Text(text = "A12")
}
Box(
modifier = Modifier
.width(Dp(1f))
.background(Color.Black)
.constrainAs(divider) {
width = Dimension.wrapContent
height = Dimension.fillToConstraints
start.linkTo(left.end)
top.linkTo(parent.top)
end.linkTo(right.start)
bottom.linkTo(parent.bottom)
}
)
Box(
modifier = Modifier
.constrainAs(right) {
width = Dimension.fillToConstraints
start.linkTo(divider.end)
top.linkTo(parent.top)
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
}
) {
Text(
text = "Test",
modifier = Modifier
.padding(vertical = Dp(100f))
.align(Alignment.Center)
)
}
}
}
The key part is using that modifier height = Dimension.fillToConstraints
来源:https://stackoverflow.com/questions/64043704/how-to-achieve-this-layout-in-jetpack-compose