So erreichen Sie dieses Layout in Jetpack Compose

Sep 24 2020

Ich versuche, das neue Jetpack Compose-UI-Framework zu verwenden, aber ich stoße auf ein Problem. Ich möchte dieses Layout erreichen, das in XML ziemlich einfach zu erreichen ist:

Aber ich kann nicht herausfinden, wie der vertikale Teiler den verfügbaren vertikalen Raum einnimmt, ohne eine feste Höhe anzugeben. Dieser Code, den ich ausprobiert habe, scheint nicht zu funktionieren:

@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))
        }
    }
}

Ich bekomme immer dieses Ergebnis:

Ich habe es auch mit ConstraintLayout versucht, aber es hat immer noch nicht funktioniert

@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
            )
        }
    }
}

Aber nichts scheint zu funktionieren. Ist das ein Fehler, eine fehlende Funktion oder fehlt mir nur etwas?

BEARBEITEN: Anscheinend besteht das eigentliche Problem darin, dass der Teiler nicht weiß, wie er messen soll, wenn die Oberfläche keine feste Höhe hat. Wenn Sie die Höhe auf eine bestimmte Zahl einstellen, wird das Problem behoben, aber die Ansicht passt sich nicht an die Höhe des Inhalts an Das kann also nicht mehr die Lösung sein

Antworten

2 MikeScamell Feb 19 2021 at 02:49

Sie können Intrinsic.Maxfür die preferredHeightvon Roweinstellen, dann setzen Sie die Spacer, um die maximale Höhe zu füllen. Weitere Informationen zu Intrinsics finden Sie in diesem Codelab-Abschnitt .

@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))
        }
    }
}
2 GabrieleMariotti Sep 24 2020 at 16:56

Mit können 1.0.0-beta02Sie sich bewerben:

  • der Modifikator .height(IntrinsicSize.Max)zumRow
  • die Modifikatoren .width(1.dp).fillMaxHeight()für dieSpacer

Weitere Informationen zu den intrinsischen Messungen finden Sie hier .

Etwas wie:

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(...)
}

1 Lukas1 Dec 22 2020 at 23:21

Ich habe es mithilfe des Einschränkungslayouts gelöst:

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)
            )
        }
    }
}

Der Schlüsselteil ist die Verwendung dieses Modifikators height = Dimension.fillToConstraints