我正在尝试使用 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 没有提供更干净的方法来实现这一目标
您是否尝试过 constrainAs 内的可见性属性。
// ...
Modifier
.constrainAs(title) {
bottom.linkTo(profilePic.top, margin = 16.dp)
start.linkTo(parent.start)
visibility = if (isTitleVisible) Visibility.Visible else Visibility.Gone
}
// ...
这就是
ConstraintLayout
的工作方式以及 View.GONE
的含义。
如果您想要
Constraints
尊重视图,即使它不是“可见的”,请使用 View.INVISIBLE
。
编写了一个小函数,即使目标消失,它也会添加零空间并处理约束。只需传递约束和逻辑即可显示或不显示。
@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)
}
}
}
您的代码中有一个遗漏。
val (text1, text2) = createRefs()
这应该位于 ContsrainLayout {} 块内,否则它将引用 focusRequester 中的 createRef,因为它也公开了相同的方法。