自从切换到 ConstraintLayout 版本 1.1.0-beta4 后,我的一些布局出现了问题。在进行任何更改之前,我想更好地了解边距在 ConstraintLayout
链中的工作原理。在下文中,我将 ConstraintLayout
1.0.2 版与 1.1.0-beta4 版中的布局进行了比较,但我认为该问题首先出现在 1.1.0-beta2 版中。
我的目标是让一些 TextView 在屏幕上拉伸(stretch),在第一个和第二个 TextView 以及第二个和第三个 TextView 之间留有间隙。背景应显示在这些边距中。为此,我创建了一个水平链并指定了从左侧 TextView 到中心 TextView 的结束边距以及从中心 TextView 到右侧 TextView 的结束边距。水平链样式为spread_inside
。
示例 1 - 使用 ConstraintLayout 版本 1.0.2
这就是版本 1.0.2 中的样子,也是我所期望的。
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/holo_blue_light">
<TextView
android:id="@+id/tvLeft"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="Text1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tvCenter"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tvCenter"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="Text2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tvRight"
app:layout_constraintStart_toEndOf="@+id/tvLeft"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tvRight"
android:layout_width="0dp"
android:layout_height="35dp"
android:background="@android:color/white"
android:gravity="center"
android:text="Text3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tvCenter"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>
示例 2 - 使用 ConstraintLayout 版本 1.1.0-beta4
此布局在 ConstraintLayout
的 1.1.0-beta4 版中如下所示。请注意边距已经消失。我希望这看起来应该与示例 1 相同,但事实并非如此。
示例 3 - 使用带开始边距的 ConstraintLayout 版本 1.1.0-beta4
如果我采用相同的布局并简单地将 8dp
的起始页边距添加到右侧 TextView (tvRight
),我的页边距不仅会重新出现在中心和右侧之间 TextView ,但也在左侧和中心 TextView 之间,尽管我没有更改那里的边距。
这不仅仅是突然兑现之前设定的利润率。如果我将最右侧 TextView 的起始边距设置为“48dp”,则看起来是 48dp
的边距也会出现在左侧和中间 TextView 之间。
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/holo_blue_light">
<!-- TextViews tvLeft & tvRight not shown but are the same as above.-->
<TextView
android:id="@+id/tvRight"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="48dp"
android:background="@android:color/white"
android:gravity="center"
android:text="Text3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tvCenter"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>
所以,我的问题是,“为什么我会看到这些结果?” ConstraintLayout
链,尤其是 spread_inside
链如何处理边距?链边距的处理方式是否发生了变化,或者我遗漏了什么?我正在寻找解释或引用一些解释所有这些的文档。
最佳答案
我找不到对这个确切问题给出权威答案的文档。然而,在 the API documentation for ConstraintLayout
中有一些关于边距的讨论。 :
If side margins are set, they will be applied to the corresponding constraints (if they exist)
在链的特定实例中,每个 View 之间都有双向约束。也就是说,不仅 View A 的结束被限制为 View B 的开始,而且 View B 的开始也被限制为 View A 的结束。
在您发布的布局中, View A 有一个结束约束和一个结束边距,但 View B 有一个没有起始边距的开始约束。据我所知,这意味着您的布局中存在相互冲突的规则( View A 希望与 View B 相距 8dp,但 View B 希望与 View A 相距 0dp)。也许不同版本的 ConstraintLayout 库有不同的策略来 (a) 确定这是否算作冲突,以及 (b) 如果算作冲突则解决冲突。
通过实验,以下是我如何在不同的 ConstraintLayout 库版本上找到在链中工作的边距:
版本 1.0.2
链中每个 View 的边距不依赖于或影响链中的其他 View 。这对行为有(至少)两个明显的影响。首先,向一个 View 添加边距会将另一个 View 推开该数量,而不管该 View 的边距如何。其次,为一个 View 添加边距不会影响链中下游 View 的边距(例如,在第一个 View 上放置 8dp 的结束边距本身不会导致第二个和第三个 View 之间出现 8dp 的空间)。
版本 1.1.0-beta4
链中每个 View 的边距都依赖于并影响链中的其他 View 。同样,这对行为有两个明显的影响。首先,向一个 View 添加边距不会将另一个 View 推开,除非它也有相同数量的边距*。其次,在链的第一个和第二个 View 之间添加边距也会影响链的第二个和第三个 View 之间的间距**。
*:似乎 1.1.0-beta4 只允许开始边距将 View 分开,而只允许结束边距没有效果。无论如何,我建议匹配边距。
**:我怀疑这是因为链试图平均分配“空间”。 View A 和 B 之间的边距产生了一个间隙,并且由于链希望强制执行一致的间距,因此它在 View B 和 C 之间增加了一个类似的间隙。
示例:
精简后,这里的布局与您的原始布局一样,边距略有变化。我保留所有其他属性不变。
<android.support.constraint.ConstraintLayout>
<TextView
android:layout_marginEnd="8dp"/>
<TextView
android:layout_marginStart="8dp"/>
<TextView/>
</android.support.constraint.ConstraintLayout>
v1.0.2:
v1.1.0-beta4:
这应该说明库版本之间的两个差异。同样,我完全找不到解释这一切的官方文档,但仅基于实验似乎是正确的。
关于android - ConstraintLayout 1.1.0(测试版)中链中的边距如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47931430/