我注意到ConstraintLayout行为从1.1.2到1.1.3发生了奇怪的变化,这可能会导致布局出现很多问题。另外,我个人认为这是一个错误,因为这种行为应该是错误的。
检查以下布局:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/test1_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test1"
app:layout_constraintTop_toTopOf="@id/test2_btn"
app:layout_constraintBottom_toBottomOf="@id/test2_btn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/test2_btn"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintHorizontal_bias="1"/>
<Button
android:id="@+id/test2_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/test1_btn"/>
</android.support.constraint.ConstraintLayout>
这是在1.1.2
的{{1}}和1.1.3
版本中如何呈现此布局的方法:
现在,我们将ConstraintLayout
添加到android:visibility="gone"
。在test1_btn
版本ConstraintLayout
中,布局呈现如下:
这完全合乎逻辑,因为我们设置了1.1.2
,所以app:layout_constraintHorizontal_bias="1"
应该位于链的最右边。现在,如果我们使用test2_btn
版本ConstraintLayout
,则布局将如下所示:
发生了什么事?为什么我失去了连锁偏见?
答案 0 :(得分:4)
要在仍使用1.1.3版本时获得旧的行为,请将此属性添加到您的<ConstraintLayout>
标记中:
app:layout_optimizationLevel="direct|barrier"
ConstraintLayout库的1.1版引入了new optimizations。这些优化功能会解析您的ConstraintLayout并查找可以删除或简化的约束。
从1.1.2版开始,默认情况下唯一启用的优化是直接和障碍。版本1.1.3 也 enables chain by default。您可以通过手动指定应启用哪些优化来返回1.1.2行为。
以另一种方式证明这是真正的问题,我在使用版本1.1.2时尝试启用链优化。
第一个屏幕截图是使用1.1.2版和您发布的布局(添加了android:gone
属性)拍摄的。然后,我将此属性添加到根ConstraintLayout
标记中:
app:layout_optimizationLevel="chains"
现在我看到的是您在1.1.3版中发现的相同行为:
答案 1 :(得分:2)
我似乎已经确定了问题,但不是因为您认为恕我直言。如果您在“定位”下查看ConstraintLayout
偏向的documention,它会指出:
遇到这种相反的约束时,默认值是将小部件居中;但是您可以使用bias属性调整位置,使一侧偏向另一侧:
layout_constraintHorizontal_bias
将应用于窗口小部件而不是链。但是,如果链是打包链并且对链中的小部件施加了偏差,则链的偏差会受到影响。目前尚不清楚当链为spread_inside
时会发生什么情况,因为这种链类型指示末端小部件粘附在侧面。
相同的文档指出:
GONE
窗口小部件通常不会显示,也不是布局本身的一部分(即,如果标记为GONE
,它们的实际尺寸将不会更改)。但是在布局计算方面,
GONE
小部件仍然是其中的一部分,但有重要区别:
- 对于布局遍,其尺寸将被视为零(基本上,它们将被解析为一个点)
- 如果它们对其他小部件有约束,它们仍将受到尊重,但是任何边距都将等于零。
因此,GONE
小部件仍应参与该链-它的尺寸仅为零。在您的示例中,当左TextView
的可见性更改为TextView
时,我希望右GONE
保持静止。因此,1.1.2的行为似乎是正确的,而1.1.3的行为似乎与文档不一致。
答案 2 :(得分:2)
我同意Cheticamp的许多回答,但我想指出一些问题。
目前尚不清楚当链条展开时会发生什么情况,因为这种链条类型指示末端小部件粘附在侧面。
偏差仅在两种情况下适用:
对于内部扩散链,偏差不起作用;其他约束将其覆盖。
因此,GONE小部件仍应参与该链-它的尺寸仅为零。
这是问题的真正症结所在。我看到文档中的一行写着“就布局计算而言,GONE小部件仍然是其中的一部分”,所以我理解您如何得出结论。
但是,我认为还有一个方向需要争论。而不是两个元素的链,想象一个三个元素的链。有了链头VISIBLE
,您就可以看到
View1 <--- space ---> View2 <--- space ---> View3
现在,当您将链头设置为GONE
时,您会期望什么?我认为大多数开发人员都希望看到以下内容:
View2 <-------------- space --------------> View3
比这个:
<----- space ----> View2 <----- space ----> View3
如果您同意,并且您认为通常,则Android开发人员宁愿看到“向内扩散”链的静止视图VISIBLE
被“正常”推到边缘,那么我认为该论点的逻辑结论是v1.1.3中可见的新行为。
我认为应该对文档进行更新以澄清这种情况。 GONE
视图参与链(只是作为一个隐形点),或 GONE
视图都不参与链(除非修改链头属性整个链)。