Jetpack Compose에서이 레이아웃을 달성하는 방법

Sep 24 2020

새로운 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))
        }
    }
}

이 결과를 계속 얻습니다.

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

그러나 아무것도 작동하지 않는 것 같습니다. 버그입니까, 누락 된 기능입니까, 아니면 그냥 누락 된 것이 있습니까?

편집 : 분명히 실제 문제는 표면에 고정 높이가 없을 때 분할기가 측정하는 방법을 모르고 높이를 일부 숫자와 동일하게 설정하면 문제가 해결되지만 뷰가 콘텐츠 높이에 적응하지 않는다는 것입니다 더 이상, 그래서 이것은 해결책이 될 수 없습니다

답변

2 MikeScamell Feb 19 2021 at 02:49

Intrinsic.Max의 preferredHeight에 대해 Row설정 한 다음을 설정하여 Spacer최대 높이를 채울 수 있습니다 . 이 코드 랩 섹션 에서 Intrinsics에 대해 자세히 알아볼 수 있습니다 .

@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

1.0.0-beta02당신 과 함께 신청할 수 있습니다 :

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

1 Lukas1 Dec 22 2020 at 23:21

제약 레이아웃을 사용하여 해결했습니다.

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

핵심 부분은 해당 수정자를 사용하는 것입니다. height = Dimension.fillToConstraints