android - ConstraintLayout 1.1.0(测试版)中链中的边距如何工作

标签 android android-layout android-constraintlayout

自从切换到 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 中的样子,也是我所期望的。

enter image description here

<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 相同,但事实并非如此。

enter image description here

示例 3 - 使用带开始边距的 ConstraintLayout 版本 1.1.0-beta4

如果我采用相同的布局并简单地将 8dp 的起始页边距添加到右侧 TextView (tvRight),我的页边距不仅会重新出现在中心和右侧之间 TextView ,但也在左侧和中心 TextView 之间,尽管我没有更改那里的边距。

[image]

这不仅仅是突然兑现之前设定的利润率。如果我将最右侧 TextView 的起始边距设置为“48dp”,则看起来是 48dp 的边距也会出现在左侧和中间 TextView 之间。

enter image description here

<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:

enter image description here

v1.1.0-beta4:

enter image description here

这应该说明库版本之间的两个差异。同样,我完全找不到解释这一切的官方文档,但仅基于实验似乎是正确的。

关于android - ConstraintLayout 1.1.0(测试版)中链中的边距如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47931430/

相关文章:

Android OpenGL 应用程序在模拟器中加载后停止工作

java - 按home键时如何防止onPause()?

java - 添加标记到 Google map - Android (JAVA)

android - 服务 onStartCommand 抛出 NullPointerException

旋转时Android应用程序崩溃

android - 约束布局 : Unable to scale image to fit a ratio in RecyclerView

android - 一起使用 GridLayout 和 ConstraintLayout 时已经定义了属性 "orientation"

Android 应用程序在启动时不断崩溃

android - 如何在 android 运行时动态准备 ui?

ScrollView 内的Android约束布局高度无效