使用 Compose ConstraintLayout 时如何处理丢失/“消失”的视图

问题描述 投票:0回答:4

我正在尝试使用 Jetpack Compose ConstraintLayout,如果所有视图都可见,则说明效果很好。 但如果缺少其中一个视图,沙堡就会倒塌。

例如,如果视图是可选的,我会这样管理它:

val (text1, text2) = createRefs()

ConstraintLayout {
    if (myTextStr.isNotEmpty()) {
        Text(
            text = myTextStr,
            modifier = Modifier
                .constrainAs(text1) {
                    start.linkTo(parent.start)
                    bottom.linkTo(parent.bottom)
                })
    }
    Text(
        text = myTextStr2,
        modifier = Modifier
            .constrainAs(text2) {
                start.linkTo(parent.start)
                bottom.linkTo(text1.top)
            })
}

但是,如果第一个文本元素丢失,那么所有布局都会被破坏,因为第二个文本位置取决于它。

一种可能性是保留文本视图,但如果 myTextStr 为 null 或为空,则将高度设置为

0.dp
。但我想确保 Compose ConstraintLayout 没有提供更干净的方法来实现这一目标

android android-jetpack-compose android-constraintlayout
4个回答
6
投票

您是否尝试过 constrainAs 内的可见性属性。

// ...
Modifier
  .constrainAs(title) { 
      bottom.linkTo(profilePic.top, margin = 16.dp) 
      start.linkTo(parent.start) 
      visibility = if (isTitleVisible) Visibility.Visible else Visibility.Gone 
}
// ...

0
投票

这就是

ConstraintLayout
的工作方式以及
View.GONE
的含义。

如果您想要

Constraints
尊重视图,即使它不是“可见的”,请使用
View.INVISIBLE


0
投票

编写了一个小函数,即使目标消失,它也会添加零空间并处理约束。只需传递约束和逻辑即可显示或不显示。

@Composable
inline fun <T : Any?> T?.ConditionalConstraintChildView(
    constraintModifier: Modifier,
    noinline doShow: (() -> Boolean) = { true },
    crossinline content: @Composable (T) -> Unit
) {
    val value = this
    Box(modifier = constraintModifier, contentAlignment = Alignment.CenterStart) {
        if (value == null || !doShow.invoke()) {
            Spacer(Modifier.size(0.dp))
        } else {
            content(value)
        }
    }
}


0
投票

您的代码中有一个遗漏。

val (text1, text2) = createRefs()

这应该位于 ContsrainLayout {} 块内,否则它将引用 focusRequester 中的 createRef,因为它也公开了相同的方法。

© www.soinside.com 2019 - 2024. All rights reserved.