线性布局的一个常见用途是均匀空间(权重)视图,例如:

如何使用新的ConstraintLayout实现这样的等距视图?

ConstraintLayout链接参考:博客文章,I/O会话视频


使用ConstraintLayout有两种方法来实现这一点:链和指南。要使用Chains,请确保您使用的是ConstraintLayout Beta 3或更新版本,如果您想在Android Studio中使用可视化布局编辑器,请确保您使用的是Android Studio 2.3 Beta 1或更新版本。

方法1 -使用链条

打开布局编辑器,像往常一样添加小部件,根据需要添加父约束。在这种情况下,我添加了两个带有约束的按钮到父按钮的底部和父按钮的一侧(左侧为保存按钮,右侧为共享按钮):

注意,在这种状态下,如果我切换到横向视图,视图不会填充父视图,而是固定在角落上:

通过Ctrl/Cmd单击或拖动一个框来突出显示两个视图:

然后右键单击视图,选择“水平居中”:

这将在视图之间建立双向连接(Chain就是这样定义的)。默认情况下,链样式是“spread”,即使没有包含XML属性也会应用该样式。坚持这种链样式,但将视图的宽度设置为0dp,可以让视图填充可用空间,均匀地分布在父视图上:

这在景观视图中更为明显:

如果你喜欢跳过布局编辑器,生成的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>

细节:

setting the width of each item to 0dp or MATCH_CONSTRAINT lets the views fill the parent (optional) the views must be linked together bidirectionally (right of save button links to share button, left of share button links to save button), this will happen automatically via the layout editor when choosing "Center Horizontally" the first view in the chain can specify the chain style via layout_constraintHorizontal_chainStyle, see the documentation for various chain styles, if the chain style is omitted, the default is "spread" the weighting of the chain can be adjusted via layout_constraintHorizontal_weight this example is for a horizontal chain, there are corresponding attributes for vertical chains

方法2 -使用指南

在编辑器中打开你的布局,点击指导线按钮:

然后选择“添加垂直引导线”:

一个新的指导方针将会出现,默认情况下,它可能会被锚定在相对值的左边(由朝左的箭头表示):

单击朝左的箭头将其切换为百分比值,然后拖动指导线到50%标记:

该指导原则现在可以用作其他视图的锚点。在我的例子中,我将保存按钮的右侧和共享按钮的左侧附加到指导方针:

如果你想要视图填充可用空间,那么约束应该设置为“任意大小”(水平运行的弯曲线):

(这与将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"和 约束布局最好的地方是它支持循环依赖,这就是我使用它所做的。

第一个孩子 应用:layout_constraintEnd_toStartOf =“@ + id / textInputSecondChild”

对于第二个孩子

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",并链接每个视图与邻居,如:

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>

Note

width = 0dp (MATCH_CONSTRAINT) button1和button2的约束必须像上面那样

结果

更多的 如果你想让View1比View2大,你可以使用权重或百分比。 例如,View1宽度= 2 *View2宽度使用权重

<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" />