ConstraintLayout行为从1.1.2到1.1.3的奇怪变化

时间:2018-11-26 09:16:15

标签: android android-constraintlayout

我注意到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版本中如何呈现此布局的方法:

enter image description here

现在,我们将ConstraintLayout添加到android:visibility="gone"。在test1_btn版本ConstraintLayout中,布局呈现如下:

enter image description here

这完全合乎逻辑,因为我们设置了1.1.2,所以app:layout_constraintHorizontal_bias="1"应该位于链的最右边。现在,如果我们使用test2_btn版本ConstraintLayout,则布局将如下所示:

enter image description here

发生了什么事?为什么我失去了连锁偏见?

3 个答案:

答案 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视图都不参与链(除非修改链头属性整个链)。