自从转换到ConstraintLayout版本1.1.0-beta4后,我的布局已经爆炸了。在进行任何更改之前,我希望更好地了解边距在ConstraintLayout
链中的工作原理。在下文中,我将ConstraintLayout
版本1.0.2中的布局与版本1.1.0-beta4进行了比较,但我认为该问题首先出现在1.1.0-beta2中。
我的目标是让一些文本视图在屏幕上伸展,第一和第二文本视图之间以及第二和第三文本视图之间存在间隙。背景应显示在这些边距中。为此,我创建一个水平链并指定从左侧文本视图到中心文本视图的结束边距以及从中心文本视图到右侧文本视图的结束边距。水平链样式为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
的起始边距添加到右侧文本视图(tvRight
),我的边距不仅会再次出现在中央和右侧文本视图之间,还会出现在左侧和中间的文本视图,虽然我没有改变那里的边距。
这不仅仅是之前设定的利润突然被尊重。如果我将最右边文本视图的起始边距设置为“48dp”,则左侧和中心文本视图之间也会显示48dp
边距。
<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
链?链条利润的处理方式是否发生变化,或者我遗漏了什么?我正在寻找解释或参考一些解释所有这些的文档。
答案 0 :(得分:8)
我找不到能够给出这个确切问题的权威答案的文档。但是,the API documentation for ConstraintLayout
中有一些关于边距的讨论:
如果设置了边距,它们将应用于相应的约束(如果存在)
在链的特定实例中,每个视图之间都有双向约束。也就是说,View A的结尾不仅限于View B的开始,而且View B的开始也受限于View A的结束。
在发布的布局中,视图A具有结束约束和结束边距,但视图B具有没有开始边距的开始约束。据我所知,这意味着您的布局中存在冲突的规则(视图A希望距视图B 8dp,但视图B希望从视图A获得0dp)。也许不同版本的ConstraintLayout库有不同的策略(a)确定这是否算作冲突,(b)如果是这样解决冲突。
通过实验,以下是我在不同的ConstraintLayout库版本中找到在链中工作的边距的方法:
链中每个视图的边距不依赖于或影响链中的其他视图。这对行为有(至少)两个可见影响。首先,无论视图的边距如何,为一个视图添加边距都会将另一个视图推向该数量。其次,为一个视图添加边距不会影响链条下方的视图边距(例如,在第一个视图上放置8dp结束边距本身也不会导致在第二个和第三个视图之间出现8dp的空间)。
链中每个视图的边距都依赖于并影响链中的其他视图。同样,这对行为有两个明显的影响。首先,为一个视图添加边距不会推动另一个视图,除非它还具有相同数量的边距*。其次,在链的第一个和第二个视图之间添加边距也会影响链的第二个和第三个视图之间的间距**。
*:似乎1.1.0-beta4只允许一个起始边距推动视图分开,而只是一个结束边距将没有任何影响。无论如何,我建议匹配边距。
**:我怀疑这是因为该连锁店正试图分配&#34;空间&#34;均匀。视图A和视图B之间的边距产生间隙,并且由于链条想要强制执行一致的间距,因此在视图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:
这应该说明库版本之间的两个不同之处。同样,我完全无法找到解释所有这些内容的官方文档,但仅仅基于实验似乎是正确的。
答案 1 :(得分:4)
扩展Ben P.的答案,我已经确定了以下ConstraintLayout
链中的边距。此信息适用于ConstraintLayout
版本1.1.0-beta4。
在一个链中,所有起始边距(android:layout_marginStart
)都得到尊重。这意味着视图之间的间距不会小于指定的起始边距。但是,间距可能更大,如下所述。
结束边距(android:layout_marginEnd
)没有相关性,似乎被忽略了。这不适用于链末端视图的末端边距,而只适用于视图交叉链接以创建链的内边距。
当链条在其约束范围内居中时,链条位于链条头部的起始边距和链条尾部的末端边缘之间。
在下面的示例中,视图“A”,“D”ang“G”被约束到父开始。视图“C”,“F”和“I”被约束到父端。
packed
如果链式样式为“已打包”,则所有视图都以指定的起始边距分开端到端分隔。视图之间的间距可以根据定义起始边距的方式而变化。在下图中,视图的宽度为match_constraints
,边距按指示设置。
如果视图的宽度设置为match_constraints
以外的其他值,则视图仍然以指定的边距打包,但链在链的头部的起始边距和链的末端边距之间居中尾。
我采用这种解释而不是考虑将末尾边距附加到结束视图,因为Android Studio设计师具有相同的解释:
spread
在“spread”链样式中,所有视图都分布在开始和结束约束之间,使得每个视图之前和之后的空间相同并且等于定义的最大起始边距。如果每个视图的宽度为match_constraints
,则默认情况下所有视图的宽度都相同。
spread_inside
spread_inside
样式的链将采用链的第一个视图并将其锚定到其起始约束,同时保证其起始边距。结束视图将锚定到其结束约束,同时尊重其结束边距。内部视图将在视图之间以相等的间距分布,如spread
链。
下面是设置了各种边距的相同布局。视图“F”和“我”的起始边距为8dp
,但差距已扩展为16dp
。视图“G”,“H”和“I”都具有相同的宽度,尽管它们看起来并不相同。
此布局的XML显示在本文末尾。
感兴趣但并不重要:如果视图的宽度为match_constraints
且所有边距均为零,则不同的链类型无法区分。
以上信息也适用于垂直链。将android:layout_marginTop
替换为android:layout_marginStart
,将android:layout_marginBottom
替换为android:layout_marginEnd
。
<强>布局强>
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light">
<TextView
android:id="@+id/heading1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="packed, match_constraints"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/textA"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginTop="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="A"
android:textColor="@android:color/black"
app:layout_constraintEnd_toStartOf="@+id/textB"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/heading1"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
app:layout_constraintEnd_toStartOf="@id/textB"
app:layout_constraintTop_toTopOf="@id/textB" />
<TextView
android:id="@+id/textB"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:background="@android:color/darker_gray"
android:gravity="center"
android:text="B"
android:textColor="@android:color/white"
app:layout_constraintEnd_toStartOf="@+id/textC"
app:layout_constraintStart_toEndOf="@+id/textA"
app:layout_constraintTop_toTopOf="@+id/textA"
tools:ignore="HardcodedText" />
<View
android:id="@+id/view16dpOnC"
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#fffb00"
app:layout_constraintEnd_toStartOf="@id/textC"
app:layout_constraintTop_toTopOf="@+id/textC" />
<TextView
android:id="@+id/textC"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="16dp"
android:background="@android:color/white"
android:gravity="center"
android:text="C"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textB"
app:layout_constraintTop_toTopOf="@+id/textA"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/heading2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="spread, match_constraints"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/textA"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#00ff19"
app:layout_constraintEnd_toStartOf="@id/textD"
app:layout_constraintTop_toTopOf="@id/textD" />
<TextView
android:id="@+id/textD"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginTop="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="D"
android:textColor="@android:color/black"
app:layout_constraintEnd_toStartOf="@+id/textE"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/heading2"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#fffb00"
app:layout_constraintEnd_toStartOf="@id/textE"
app:layout_constraintTop_toTopOf="@id/textE" />
<TextView
android:id="@+id/textE"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="16dp"
android:background="@android:color/darker_gray"
android:gravity="center"
android:text="E"
android:textColor="@android:color/white"
app:layout_constraintEnd_toStartOf="@+id/textF"
app:layout_constraintStart_toEndOf="@+id/textD"
app:layout_constraintTop_toTopOf="@+id/textD"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#003cff"
app:layout_constraintStart_toEndOf="@id/textE"
app:layout_constraintTop_toTopOf="@+id/textE" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
app:layout_constraintEnd_toStartOf="@id/textF"
app:layout_constraintTop_toTopOf="@id/textF" />
<TextView
android:id="@+id/textF"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="F"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textE"
app:layout_constraintTop_toTopOf="@+id/textD"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#00ff19"
app:layout_constraintStart_toEndOf="@id/textF"
app:layout_constraintTop_toTopOf="@id/textF" />
<TextView
android:id="@+id/heading3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="spread_inside, match_constraints"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/textD"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#003cff"
app:layout_constraintEnd_toStartOf="@id/textG"
app:layout_constraintTop_toTopOf="@+id/textG" />
<TextView
android:id="@+id/textG"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="G"
android:textColor="@android:color/black"
app:layout_constraintEnd_toStartOf="@+id/textH"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/heading3"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#fffb00"
app:layout_constraintEnd_toStartOf="@id/textH"
app:layout_constraintTop_toTopOf="@id/textH" />
<TextView
android:id="@+id/textH"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="16dp"
android:background="@android:color/darker_gray"
android:gravity="center"
android:text="H"
android:textColor="@android:color/white"
app:layout_constraintEnd_toStartOf="@+id/textI"
app:layout_constraintStart_toEndOf="@+id/textG"
app:layout_constraintTop_toTopOf="@+id/textG"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#003cff"
app:layout_constraintStart_toEndOf="@id/textH"
app:layout_constraintTop_toTopOf="@id/textH" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
app:layout_constraintEnd_toStartOf="@id/textI"
app:layout_constraintTop_toTopOf="@id/textI" />
<TextView
android:id="@+id/textI"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:background="@android:color/white"
android:gravity="center"
android:text="I"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textH"
app:layout_constraintTop_toTopOf="@+id/textG"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@id/textC"
app:layout_constraintTop_toTopOf="@id/textC" />
<View
android:id="@+id/view8dp"
android:layout_width="8dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:background="#ff00cc"
app:layout_constraintBottom_toTopOf="@id/view8dpGap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textG"
app:layout_constraintVertical_bias="0.100000024"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/text8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="8dp start margin"
app:layout_constraintBottom_toBottomOf="@+id/view8dp"
app:layout_constraintStart_toEndOf="@id/view8dp"
app:layout_constraintTop_toTopOf="@+id/view8dp"
tools:ignore="HardcodedText" />
<View
android:id="@+id/view8dpGap"
android:layout_width="8dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:background="#003cff"
app:layout_constraintBottom_toTopOf="@+id/view16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view8dp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="8dp gap not defined by start margin"
app:layout_constraintBottom_toBottomOf="@+id/view8dpGap"
app:layout_constraintStart_toEndOf="@+id/view8dpGap"
app:layout_constraintTop_toTopOf="@+id/view8dpGap"
tools:ignore="HardcodedText" />
<View
android:id="@+id/view16dp"
android:layout_width="17dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:background="#fffb00"
app:layout_constraintBottom_toTopOf="@+id/view16dpGap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view8dpGap" />
<TextView
android:id="@+id/text16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="16dp start margin"
app:layout_constraintBottom_toBottomOf="@+id/view16dp"
app:layout_constraintStart_toEndOf="@+id/view16dp"
app:layout_constraintTop_toTopOf="@+id/view16dp"
tools:ignore="HardcodedText" />
<View
android:id="@+id/view16dpGap"
android:layout_width="17dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:background="#00ff19"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view16dp" />
<TextView
android:id="@+id/text16dpGap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="16dp gap not defined by start margin"
app:layout_constraintBottom_toBottomOf="@+id/view16dpGap"
app:layout_constraintStart_toEndOf="@+id/view16dpGap"
app:layout_constraintTop_toTopOf="@+id/view16dpGap"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>
答案 2 :(得分:-2)
在constraintLayout中,链式工作方式如下
1.Spread:视图均匀分布。例如。 应用:layout_constraintHorizontal_chainStyle =”蔓延” 应用程式:layout_constraintVertical_chainStyle =”传播”
2.内部扩展:第一个和最后一个视图附加在链的每一端的约束上,其余视图均匀分布。例如。 应用程式:layout_constraintHorizontal_chainStyle =” spread_inside” 应用程式:layout_constraintVertical_chainStyle =” spread_inside”
3.Packed:视图被打包在一起(在考虑边距后)。然后,您可以通过更改链的头部视图偏差来调整整个链的偏差(左/右或上/下)。例如。 应用:layout_constraintHorizontal_chainStyle =”打包” 应用程式:layout_constraintVertical_chainStyle =”打包”
4.Weighted:当链设置为展开或展开时,您可以通过将一个或多个视图设置为“匹配约束”(0dp)来填充剩余空间。默认情况下,空间均匀分布在每个视图之间,这些视图设置为&#34;匹配约束,&#34;但您可以使用layout_constraintHorizontal_weight和layout_constraintVertical_weight属性为每个视图指定重要性权重。如果您在线性布局中熟悉layout_weight,则其工作方式相同。因此,具有最高权重值的视图获得最大的空间;具有相同权重的视图获得相同的空间量。
有关详细信息,请参阅下面的图片