约束布局 ConstraintLayout 的使用(二)

本贴最后更新于 2238 天前,其中的信息可能已经渤澥桑田

ConstraintLayout 可用的约束 (constraint-layout:1.0.2)

  • 相对定位
  • 边距(Margins)
  • 中心定位
  • 可见性行为(View.GONE)
  • 链(Chains)
  • 虚拟助手对象(Guideline)

相对定位

相对定位是 ConstraintLayout 创建布局的基本组成部分之一。这些约束允许你指定控件相对于另一个位置。
例如,按钮 B 要位于按钮 A 的右边

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ButtonA"/>

    <Button
        android:id="@+id/buttonB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ButtonB"
        app:layout_constraintLeft_toRightOf="@id/buttonA"/>

可用的约束属性:

  • layout_constraintLeft_toLeftOf (该控件的左边与指定控件的左边对齐)

  • layout_constraintLeft_toRightOf (该控件的左边与指定控件的右边对齐)

  • layout_constraintRight_toLeftOf

  • layout_constraintRight_toRightOf

  • layout_constraintTop_toTopOf

  • layout_constraintTop_toBottomOf

  • layout_constraintBottom_toTopOf

  • layout_constraintBottom_toBottomOf

  • layout_constraintBaseline_toBaselineOf

  • layout_constraintStart_toEndOf

  • layout_constraintStart_toStartOf

  • layout_constraintEnd_toStartOf

  • layout_constraintEnd_toEndOf

    上面的属性除了可以指定控件 id,还可以使用_parent_(父容器,即 ConstraintLayout)

边距

与 RelativeLayout 一样。属性列表

  • android:layout_marginStart

  • android:layout_marginEnd

  • android:layout_marginLeft

  • android:layout_marginTop

  • android:layout_marginRight

  • android:layout_marginBottom

    与 RelativeLayout 不一样的是,当约束目标_visibility_属性设为 GONE 时,你还可以通过下面的属性设定边距:

  • layout_goneMarginStart

  • layout_goneMarginEnd

  • layout_goneMarginLeft

  • layout_goneMarginTop

  • layout_goneMarginRight

  • layout_goneMarginBottom

如下面的例子:

<android.support.constraint.ConstraintLayout ...>

    <Button
        android:id="@+id/buttonA" ...
        android:visibility="gone"/>
    <Button
        android:id="@+id/buttonB" ...
        app:layout_goneMarginStart="20dp"
        app:layout_constraintLeft_toRightOf="@id/buttonA"/>

</android.support.constraint.ConstraintLayout>

当 buttonA 设成 gone 时,buttonA 消失,buttonB 距左边 20dp。注意,该属性只在约束目标设成 GONE 时生效,设成_visible_ 和 invisible 时该属性不起作用。

中心定位和偏移

怎么使控件居中呢?可以这样

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ButtonA"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

</android.support.constraint.ConstraintLayout>

layout_constraintLeft_toLeftOflayout_constraintRight_toRightOf 同时起作用,约束像相反的力左右拉动控件,使得部件将最终被居中在父容器。这同样适用于垂直约束。
这种情况下,默认使控件居中。但你可以使用下面的属性使控件的位置发生偏移。

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

例如,下面的设置会使控件往左偏移 30%,而不是默认的 50%:

<android.support.constraint.ConstraintLayout ...>
    <Button 
        android:id="@+id/button" ...
        app:layout_constraintHorizontal_bias="0.3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent/>
</android.support.constraint.ConstraintLayout>

尺寸限制

当 ConstraintLayout 的大小被设置成 WRAP_CONTENT 时,可以使用

  • android:minWidth (最小宽度)
  • android:minHeight (最小高度)

来进行限制

容器内的控件 android:layout_width 和 android:layout_height 有 3 种情况:

  • 使用具体的尺寸
  • 使用 WRAP_CONTENT
  • 使用 0dp,这是相当于“ MATCH_CONSTRAINT”

注意!ConstraintLayout 内的控件尽量不要使用 match_parent!
前两种与其他的布局类似,最后一种是通过其他的约束条件来确定控件的大小。
下面的代码使 buttonA 左边距父容器 50dp,右边铺满剩下的空间。

<android.support.constraint.ConstraintLayout ...>

    <Button
        android:id="@+id/buttonA"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="ButtonA"
        android:layout_marginStart="50dp"
        android:layout_marginLeft="50dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

当容器内的控件的长或者宽设为 0dp 时,可以通过 layout_constraintDimentionRatio 设置此控件的长宽比。
例如:

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="测试文字排列"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintDimensionRatio="16:9"/>

效果如下:

按钮的 宽度:高度 = 16:9 。(也可以用浮点值,表示宽度和高度之间的比率)

当宽和高都设为 0dp 时,系统将设置最大尺寸满足所有约束并保持设定的长宽比。上面的例子将 android:layout_width 改为 0dp 后效果如下:

也可以通过预先添加 W 或“H”来分别限制宽度或高度。上面的效果图代码如下:

    <Button
        android:id="@+id/buttonA"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="测试文字排列"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintDimensionRatio="h,16:9"/>

app:layout_constraintDimensionRatio=”h,16:9” 意思是通过 16:9 的比例设置 button 的高度。
感觉这个地方的 w 和 h 的设置有点难以理解,事实上,”w”或者”h”完全可以不用设置,布局可以自动推断。例如,上面的代码约束了宽度,使宽度铺满容器,而高度并没有约束,那么高度就会根据比例自动调整。

Chains

Chains 为同一方向上(水平或垂直)相互连接(或者说约束)的控件提供统一的管理。
Chains 的属性由这条 chain 上第一个控件所控制,该控件称为 chain head。

上图中控件 A 左边与父容器接触,右边与控件 B 依赖;控件 B 左边依赖于控件 A,右边依赖于控件 B;控件 C 左边依赖于控件 B,右边依赖于父容器。且该 chain 为水平方向。
用代码表示如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="buttonA"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintRight_toLeftOf="@id/buttonB"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <Button
        android:id="@+id/buttonB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="buttonB"
        app:layout_constraintLeft_toRightOf="@+id/buttonA"
        app:layout_constraintRight_toLeftOf="@id/buttonC"/>

    <Button
        android:id="@+id/buttonC"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="buttonC"
        app:layout_constraintLeft_toRightOf="@+id/buttonB"
        app:layout_constraintRight_toRightOf="parent"/>

</android.support.constraint.ConstraintLayout>

效果图:

由于 ButtonA 为 chain head。所以 layout_constraintHorizontal_chainStyle 由 ButtonA 设置。该属性表示水平方向的 chain。还有另一个属性 layout_constraintVertical_chainStyle 表示垂直方向。

该属性有三种值:

  • spread 默认值。均匀分布(控件宽为 wrap_content 或确定值)

  • spread_inside 与 spread 类型,只是 chain 两端的控件不占父容器的空间,多余的空间由 chain 里的控件平分。

  • spread_inside chain 上的所有控件居中紧挨在一起

    效果图如下:


当设置 spread 时,可以分别为每个子控件设置权重,对应的属性为 layout_constraintHorizontal_weight 和 layout_constraintVertical_weight,与 LinearLayout 的 weight 类似,需要注意的是,此时子控件的 layout_width 需要设成 0dp。

当设置 packed 时,可以设置 chain 在水平或垂直方向上的偏移量,对应的属性为 layout_constraintHorizontal_bias 和 layout_constraintVertical_bias,取值在 0 到 1 之间。

Guideline

ConstraintLayout 还可以通过创建对象 guideline 来辅助布局。
Guideline 有水平和垂直两张情况:

  • 水平(horizontal)的 Guideline 高度为 0,宽度是 ConstraintLayout 的宽度
  • 垂直(vertical)的 Guideline 宽度为 0,高度是 ConstraintLayout 的高度

Guideline 创建方式:

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        app:layout_constraintGuide_begin="52dp"
        android:orientation="vertical" />

Guideline 有三种属性:

  • layout_constraintGuide_begin 距离左侧或顶部的距离
  • layout_constraintGuide_end 距离右侧或底部的距离
  • layout_constraintGuide_percent float 类型。距离 left 或 top 的比例。

示例:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        app:layout_constraintGuide_begin="52dp"
        android:orientation="vertical" />

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="buttonA"
        app:layout_constraintLeft_toRightOf="@+id/guideline" />

</android.support.constraint.ConstraintLayout>

  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    333 引用 • 323 回帖 • 70 关注
  • 布局
    6 引用 • 3 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...