使用 ConstraintLayout 均匀间隔视图
Evenly spacing views using ConstraintLayout
LinearLayout
的一个常见用途是平均 space(权重)视图,例如:
如何使用新的 ConstraintLayout
实现像这样的 spaced 视图?
ConstraintLayout
参考链接:blog post, I/O session video
有两种方法可以使用 ConstraintLayout
完成此操作:Chains and Guidelines。要使用 Chains,请确保您使用的是 ConstraintLayout
Beta 3 或更新版本,如果您想在 Android Studio 中使用可视化布局编辑器,请确保您使用的是 Android Studio 2.3 Beta 1或更新版本。
方法 1 - 使用链
打开布局编辑器并正常添加小部件,并根据需要添加父约束。在这种情况下,我在父级的底部和父级的侧面添加了两个带有约束的按钮(左侧用于保存按钮,右侧用于共享按钮):
请注意,在这种状态下,如果我切换到横向视图,视图不会填满父视图,而是固定在角落:
通过 Ctrl/Cmd 单击或在视图周围拖出一个框来突出显示两个视图:
然后 right-click 在视图上选择 "Center Horizontally":
这会在视图之间建立一个 bi-directional 连接(这是链的定义方式)。默认情况下,链样式为 "spread",即使不包含 XML 属性也会应用。坚持这种链式风格,但将视图的宽度设置为 0dp
让视图填充可用的 space,均匀分布在父级上:
这在横向视图中更明显:
如果您希望跳过布局编辑器,生成的 XML 将如下所示:
<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/button_save"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_save_text"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button_share"
app:layout_constraintHorizontal_chainStyle="spread" />
<Button
android:id="@+id/button_share"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_share_text"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintLeft_toRightOf="@+id/button_save"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
详情:
- 将每个项目的宽度设置为
0dp
或 MATCH_CONSTRAINT
让视图填充父项(可选)
- 视图必须双向链接在一起(保存按钮右侧链接到共享按钮,共享按钮左侧链接到保存按钮),这将在选择 "Center Horizontally"[=104 时通过布局编辑器自动发生=]
- 链中的第一个视图可以通过
layout_constraintHorizontal_chainStyle
指定链样式,各种链样式见documentation,如果省略链样式,则默认为"spread"
- 链的权重可以通过
layout_constraintHorizontal_weight
调整
- 本例为横链,竖链有对应属性
方法 2 - 使用指南
在编辑器中打开布局并单击指南按钮:
然后select"Add Vertical Guideline":
将出现一个新的指南,默认情况下,它可能会锚定在相对值的左侧(由 left-facing 箭头表示):
单击 left-facing 箭头将其切换为百分比值,然后将参考线拖动到 50% 标记处:
指南现在可以用作其他视图的锚点。在我的示例中,我将保存按钮的右侧和共享按钮的左侧附加到指南中:
如果您希望视图填满可用 space,则应将约束设置为 "Any Size"(水平波浪线 运行):
(这与将 layout_width
设置为 0dp
相同)。
指南也可以在 XML 中创建,而不是使用布局编辑器:
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
好吧,如果对某人有帮助的话
键在这里app:layout_constraintHorizontal_weight="1"
和
关于约束布局的最好的事情是它支持循环依赖,这就是我使用它所做的。
第一个child
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
第二个child
app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
这里是完整的演示
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputParent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<EditText
android:id="@+id/editTextParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/state" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputFirstChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputParent">
<EditText
android:id="@+id/editTextChildOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/pin_code" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputSecondChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputParent">
<EditText
android:id="@+id/editTextChildSecond"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/country" />
</android.support.design.widget.TextInputLayout>
您应该了解加权链。这里有一个代码示例。
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/figure_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_2"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
tools:text="1"
/>
<TextView
android:id="@+id/figure_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_3"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_1"
tools:text="2"
/>
<TextView
android:id="@+id/figure_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_4"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_2"
tools:text="3"
/>
<TextView
android:id="@+id/figure_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_3"
tools:text="4"
/>
</android.support.constraint.ConstraintLayout>
因此,设置 android:layout_width="0dp"
、app:layout_constraintHorizontal_weight="1"
和 link 与邻居 luke 的每个视图:
app:layout_constraintStart_toEndOf="@id/figure_2"
app:layout_constraintEnd_toStartOf="@id/figure_4"
要在同一行创建2个视图,等宽,只需要定义
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button1" />
</android.support.constraint.ConstraintLayout>
备注
- 宽度 = 0dp (
MATCH_CONSTRAINT
)
button1
和 button2
的约束必须如上
结果
更多
如果你想要 View1
比 View2
大,你可以使用 weight
或 percent
.
例如,View1
width = 2 *View2
width use weight
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toStartOf="@+id/button4"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
/>
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/button3"
/>
</android.support.constraint.ConstraintLayout>
结果
例如,View1
宽度=2*View2
宽度使用百分比
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/button5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 5"
app:layout_constraintEnd_toStartOf="@+id/button6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.667"
/>
<Button
android:id="@+id/button6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button5"
app:layout_constraintWidth_percent="0.333"
/>
</android.support.constraint.ConstraintLayout>
结果
一旦你有了链接的项目,你仍然可以像相对布局一样在它们上使用重量来保持它们均匀分布。下面的示例显示了如何使用不同大小的 textView 使它们均匀分布。
<TextView1
app:layout_constraintHorizontal_weight="1" />
<TextView2
app:layout_constraintHorizontal_weight="1" />
<TextView3
app:layout_constraintHorizontal_weight="1" />
<TextView4
app:layout_constraintHorizontal_weight="1" />
LinearLayout
的一个常见用途是平均 space(权重)视图,例如:
如何使用新的 ConstraintLayout
实现像这样的 spaced 视图?
ConstraintLayout
参考链接:blog post, I/O session video
有两种方法可以使用 ConstraintLayout
完成此操作:Chains and Guidelines。要使用 Chains,请确保您使用的是 ConstraintLayout
Beta 3 或更新版本,如果您想在 Android Studio 中使用可视化布局编辑器,请确保您使用的是 Android Studio 2.3 Beta 1或更新版本。
方法 1 - 使用链
打开布局编辑器并正常添加小部件,并根据需要添加父约束。在这种情况下,我在父级的底部和父级的侧面添加了两个带有约束的按钮(左侧用于保存按钮,右侧用于共享按钮):
请注意,在这种状态下,如果我切换到横向视图,视图不会填满父视图,而是固定在角落:
通过 Ctrl/Cmd 单击或在视图周围拖出一个框来突出显示两个视图:
然后 right-click 在视图上选择 "Center Horizontally":
这会在视图之间建立一个 bi-directional 连接(这是链的定义方式)。默认情况下,链样式为 "spread",即使不包含 XML 属性也会应用。坚持这种链式风格,但将视图的宽度设置为 0dp
让视图填充可用的 space,均匀分布在父级上:
这在横向视图中更明显:
如果您希望跳过布局编辑器,生成的 XML 将如下所示:
<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/button_save"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_save_text"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button_share"
app:layout_constraintHorizontal_chainStyle="spread" />
<Button
android:id="@+id/button_share"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_share_text"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintLeft_toRightOf="@+id/button_save"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
详情:
- 将每个项目的宽度设置为
0dp
或MATCH_CONSTRAINT
让视图填充父项(可选) - 视图必须双向链接在一起(保存按钮右侧链接到共享按钮,共享按钮左侧链接到保存按钮),这将在选择 "Center Horizontally"[=104 时通过布局编辑器自动发生=]
- 链中的第一个视图可以通过
layout_constraintHorizontal_chainStyle
指定链样式,各种链样式见documentation,如果省略链样式,则默认为"spread" - 链的权重可以通过
layout_constraintHorizontal_weight
调整
- 本例为横链,竖链有对应属性
方法 2 - 使用指南
在编辑器中打开布局并单击指南按钮:
然后select"Add Vertical Guideline":
将出现一个新的指南,默认情况下,它可能会锚定在相对值的左侧(由 left-facing 箭头表示):
单击 left-facing 箭头将其切换为百分比值,然后将参考线拖动到 50% 标记处:
指南现在可以用作其他视图的锚点。在我的示例中,我将保存按钮的右侧和共享按钮的左侧附加到指南中:
如果您希望视图填满可用 space,则应将约束设置为 "Any Size"(水平波浪线 运行):
(这与将 layout_width
设置为 0dp
相同)。
指南也可以在 XML 中创建,而不是使用布局编辑器:
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
好吧,如果对某人有帮助的话
键在这里app:layout_constraintHorizontal_weight="1"
和
关于约束布局的最好的事情是它支持循环依赖,这就是我使用它所做的。
第一个child
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
第二个child
app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
这里是完整的演示
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputParent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<EditText
android:id="@+id/editTextParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/state" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputFirstChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputParent">
<EditText
android:id="@+id/editTextChildOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/pin_code" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputSecondChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputParent">
<EditText
android:id="@+id/editTextChildSecond"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/country" />
</android.support.design.widget.TextInputLayout>
您应该了解加权链。这里有一个代码示例。
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/figure_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_2"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
tools:text="1"
/>
<TextView
android:id="@+id/figure_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_3"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_1"
tools:text="2"
/>
<TextView
android:id="@+id/figure_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_4"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_2"
tools:text="3"
/>
<TextView
android:id="@+id/figure_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_3"
tools:text="4"
/>
</android.support.constraint.ConstraintLayout>
因此,设置 android:layout_width="0dp"
、app:layout_constraintHorizontal_weight="1"
和 link 与邻居 luke 的每个视图:
app:layout_constraintStart_toEndOf="@id/figure_2"
app:layout_constraintEnd_toStartOf="@id/figure_4"
要在同一行创建2个视图,等宽,只需要定义
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button1" />
</android.support.constraint.ConstraintLayout>
备注
- 宽度 = 0dp (
MATCH_CONSTRAINT
) button1
和button2
的约束必须如上
结果
更多
如果你想要 View1
比 View2
大,你可以使用 weight
或 percent
.
例如,View1
width = 2 *View2
width use weight
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toStartOf="@+id/button4"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
/>
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/button3"
/>
</android.support.constraint.ConstraintLayout>
结果
例如,View1
宽度=2*View2
宽度使用百分比
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/button5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 5"
app:layout_constraintEnd_toStartOf="@+id/button6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.667"
/>
<Button
android:id="@+id/button6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button5"
app:layout_constraintWidth_percent="0.333"
/>
</android.support.constraint.ConstraintLayout>
结果
一旦你有了链接的项目,你仍然可以像相对布局一样在它们上使用重量来保持它们均匀分布。下面的示例显示了如何使用不同大小的 textView 使它们均匀分布。
<TextView1
app:layout_constraintHorizontal_weight="1" />
<TextView2
app:layout_constraintHorizontal_weight="1" />
<TextView3
app:layout_constraintHorizontal_weight="1" />
<TextView4
app:layout_constraintHorizontal_weight="1" />