问题描述
免责声明:我知道Compose刚刚输入了alpha01,因此我不希望所有功能都可以 可用。但是,恕我直言,特定布局案例的布局和处理是一个重要主题 应该早点解决。
当前基于视图的 ConstraintLayout
提供了一些特定的处理方式,以防出现子视图
标记为GONE
,请参阅
ConstrainLayout documentation。
我检查了撰写 ConstraintLayout
文档,可用的修饰符等,但是
没有找到任何指向这个方向的东西。我也找不到任何有关的提示
INVISIBLE
以及撰写 ConstraintLayout
的处理方式/方式,例如基于视图的 ConstraintLayout
。
通常,当前基于视图的布局(例如LinearLayout)在一个广告素材中处理INVISIBLE
和GONE
类似的方式:
-
如果视图处于状态
INVISIBLE
,则该视图是其大小的布局的一部分,只是没有 如图所示。其他视图的整体布局不会发生变化,而是保持在原位置。 -
如果视图处于状态
GONE
,则通常将其大小视为0,并重新计算布局,然后 更改,其他视图通常会更改其位置。
这里有一个简单的Compose ConstraintLayout UI,连续只有4个按钮,链接起来很漂亮 传播。
// if dontShow is 0 then show all buttons,otherwise make the button with this number
// somehow INVISIBLE. This feature is not yet implemented.
@Composable
fun fourButtonsCL(dontShow: Int) {
ConstraintLayout(Modifier.fillMaxSize()) {
val (btn1,btn2,btn3,btn4) = createRefs()
TextButton(onClick = {},Modifier.constrainAs(btn1) {}.background(teal200)) { Text("Button1") }
TextButton(onClick = {},Modifier.constrainAs(btn2) {}.background(teal200)) { Text("Button2") }
TextButton(onClick = {},Modifier.constrainAs(btn3) {}.background(teal200)) { Text("Button3") }
TextButton(onClick = {},Modifier.constrainAs(btn4) {}.background(teal200)) { Text("Button4") }
createHorizontalChain(btn1,btn4)
}
}
@Preview(showBackground = true)
@Composable
fun previewThreeButtons() {
ComposeAppTheme {
fourButtonsCL()
}
}
假设我想使Button3
不可见,但将其他3个按钮保持在它们所处的位置
是。因此,Button2
和Button4
之间只是一个空洞。如何在不创造另一个的情况下实现这一目标
可组合或添加其他逻辑。虽然在这种简单情况下的逻辑可能只是一个观点
对于代码,更复杂的布局将需要一些更复杂的逻辑。基于veConw的ConstraintLayout
我们只需要修改子视图。
另一个假设:使Button3
从布局(GONE
)中完全消失,然后重新计算
布局,其余按钮变得更宽且均匀分布。乍一看,这看起来很简单,
在这个非常简单的示例中,这可能很容易。但是,在更复杂的布局中,这可能需要
对嵌入式Composables的约束进行了部分甚至很多重新布线。
因此,问题是:
对于Column
和Row
布局,compose如何处理这些情况(例如在基于视图的LinearLayout中)
特别是ConstraintLayout
?但是有以下限制?:未定义
许多新的Composables和/或未在Composables内部添加复杂的布局逻辑(重新布线)
约束)。
我错过了一些修饰符吗?这在可组合布局中是否有计划甚至可行?会是什么 解决Compose中此类布局问题的首选方法?
解决方法
基于@CommonsWare对我可以解决INVISIBLE
的问题的评论
选项,请参见下面的代码。
当前(在alpha-01中),ConstraintLayout的实现似乎不完整,代码中至少有几个 TODO 注释表明了这一点。这个
似乎包括GONE
功能尚未提供的支持。
我看到了其中一些:
// TODO(popam,b / 158069248):添加用于消失边距的参数
此外,链功能还无法以与 在基于视图的ConstraintLayout中。
object FourElementsNoDSL {
const val elementA = "ElementA"
const val elementB = "ElementB"
const val elementC = "ElementC"
const val elementD = "ElementD"
private val noDSLConstraintSet = ConstraintSet {
// Create references with defines ids,here using a string as id. Could be an Int as well,// actually it's defined as 'Any'
val elemA = createRefFor(elementA)
val elemB = createRefFor(elementB)
val elemC = createRefFor(elementC)
val elemD = createRefFor(elementD)
// Simple chain only. Instead of this simple chain we can use (for example):
// constrain(elemA) {start.linkTo(parent.start) }
// to set a constraint as known in XML
// constrain(elemA) {start.linkTo(parent.start,16.dp) }
// constrain(elemB) {start.linkTo(elemA.end) }
// constrain(elemC) {start.linkTo(elemB.end) }
// constrain(elemD) {end.linkTo(parent.end) }
createHorizontalChain(elemA,elemB,elemC,elemD)
}
@Composable
fun fourButtonsCLNoDSL(doNotShow: List<String>) {
ConstraintLayout(constraintSet = noDSLConstraintSet,modifier = Modifier.fillMaxSize()) {
// This block contains the children
Text(text = "A",modifier = Modifier.layoutId(elementA)
.drawOpacity(if (doNotShow.contains(elementA)) 0f else 1f)
.padding(0.dp),style = TextStyle(fontSize = 20.sp)
)
Text(text = "B",modifier = Modifier.layoutId(elementB)
.drawOpacity(if (doNotShow.contains(elementB)) 0f else 1f)
.padding(0.dp),style = TextStyle(fontSize = 20.sp)
)
Text(text = "C",modifier = Modifier.layoutId(elementC)
.drawOpacity(if (doNotShow.contains(elementC)) 0f else 1f)
.padding(0.dp),style = TextStyle(fontSize = 20.sp)
)
Text(text = "D",modifier = Modifier.layoutId(elementD)
.drawOpacity(if (doNotShow.contains(elementD)) 0f else 1f)
.padding(0.dp),style = TextStyle(fontSize = 20.sp))
}
}
}
@Preview(showBackground = true)
@Composable
fun previewFourFieldsNoDSL() {
val noShow = listOf(FourElementsNoDSL.elementC)
PlaygroundTheme {
FourElementsNoDSL.fourButtonsCLNoDSL(noShow)
}
}
object FourElementsNoDSL
定义了布局,提供了元素ID等。
这与包含这种布局的XML文件大致相当。
noDSL 表示此布局不使用Compose ConstraintLayout的Kotlin
DSL。当前,DSL不提供设置元素引用的机制
(在layoutId
中使用),其ID已在本示例中完成。