Android ConstraintLayout 详解及示例

286 阅读7分钟

前言

ConstraintLayout 可让您使用扁平视图层次结构(无嵌套视图组)创建复杂的大型布局。它与 RelativeLayout 相似,其中所有的视图均根据同级视图与父布局之间的关系进行布局,但其灵活性要高于 RelativeLayout,并且更易于与 Android Studio 的布局编辑器配合使用。

ConstraintLayout 的所有功能均可直接通过布局编辑器的可视化工具来使用,因为布局 API 和布局编辑器是专为彼此构建的。 因此,您完全可以使用 ConstraintLayout 通过拖放的形式(而非修改 XML)来构建布局。


一、ConstraintLayout属性讲解

先简单了解一下我们使用ConstraintLayout要用到的一些基本方位属性,如下表所示:

属性描述
app:layout_constraintLeft_toLeftOf把A的left side放在B的left side(左边对齐)
app:layout_constraintLeft_toRightOf把A的left side放在B的right side(左边相对右边对齐)
app:layout_constraintRight_toLeftOf把A的right side放在B的left side(右边相对左边对齐)
app:layout_constraintRight_toRightOf把A的right side放在B的right side(右边对齐)
app:layout_constraintTop_toTopOf把A的top side放在B的top side(顶部对齐)
app:layout_constraintTop_toBottomOf把A的top side放在B的bottom side(顶部相对底部对齐)
app:layout_constraintBottom_toTopOf把A的bottom side放在B的top side(底部相对顶部对齐)
app:layout_constraintBottom_toBottomOf把A的bottom side放在B的bottom side(底部对齐)
app:layout_constraintStart_toEndOf把A的start position放在B的end position(起始位置相对结束位置对齐)
app:layout_constraintStart_toStartOf把A的start position放在B的start position(起始位置对齐)
app:layout_constraintEnd_toStartOf把A的end position放在B的start position(结束位置相对起始位置对齐)
app:layout_constraintEnd_toEndOf把A的end position放在B的end position(结束位置对齐)
app:layout_constraintBaseline_toBaselineOf把A的bottom side放在B的top side(基准线对齐)

注意:属性的命名空间是app

二、偏斜(Bias)

在使用LinearLayout的时候,我们通常会使用Gravity来将水平或者垂直排列的控件按照权重的分配进行排列。而在ConstraintLayout中,它提供了bias属性来对控件进行权重的分配。

代码如下(示例):

<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="match_parent">

       <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="A"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.25"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

属性描述
app:layout_constraintHorizontal_bias水平方向偏移系数
app:layout_constraintVertical_bias垂直方向偏移系数

三、GONE不是真的GONE

我们在使用RelativeLayout开发时,经常会碰到这么一种逻辑,当某个数据为空的时候,该数据所绑定的控件则GONE掉。那么这样会出现这样的问题,例如有三个控件A、B、C垂直排列,B在A的下方,C在B的下方,那B隐藏(GONE)掉了之后,由于C对于A并没有依赖关系,所以会导致页面错误。这个问题ConstraintLayout给出了很好的解决方案。当在ConstraintLayout中,若一个控件隐藏(GONE)之后,它会变成一个点,因此对于把该控件作为参考控件的其它控件依然具有约束作用。

当这个控件隐藏之后,我们还可以参照这个隐藏的控件对其他控件设置边距的属性。

属性描述
app:layout_goneMarginLeft隐藏控件左边距
app:layout_goneMarginRight隐藏控件右边距
app:layout_goneMarginTop隐藏控件顶部边距
app:layout_goneMarginBottom隐藏控件底部边距
app:layout_goneMarginStart隐藏控件起始边距
app:layout_goneMarginEnd隐藏控件结束边距

四、宽高比

1、View的宽高比

在ConstraintLayout中,还可以将宽定义成高的一个比例或者高定义成宽的比例。首先,需要先将宽或者高设置为0dp(即MATCH_CONSTRAINT),既要适应约束条件。然后通过layout_constraintDimensionRatio属性设置一个比例即可。这个比例可以是“浮点数”,表示宽度和高度之间的比例;也可以是“宽度:高度”形式的比例。

代码如下(示例):

<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:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="-------------------宽高比2:1-------------------"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

这里将按钮的高度设置为宽度的一半了。如下图所示:
在这里插入图片描述

如果宽和高都设置为0dp(即MATCH_CONSTRAINT),那么layout_constraintDimensionRatio的值需要先加一个"W,宽度:高度"或者"H,宽度:高度"来表示约束宽度或者高度,代码如下:

<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:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="h,10:6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

效果图如下:
在这里插入图片描述

2、View百分比宽高

ConstraintLayout还能使用百分比来设置view的宽高,要使用百分比宽度或高度需要设置成0dp(即MATCH_CONSTRAINT)。
然后设置如下属性即可:

app:layout_constraintWidth_default="percent" //设置宽为百分比 
app:layout_constraintWidth_percent="0.3" //01之间的值
或
app:layout_constraintHeight_default="percent" //设置高为百分比 
app:layout_constraintHeight_percent="0.3" //01之间的值

五、复杂布局的福星-Chain属性

Chain链时一种特殊的约束让多个chain链链接的Views能够平分剩余空间位置,在Android传统布局特征里面最相似的应该是LinearLayout中的权重比weight,但Chains链能做到的远远不止权重比weight的功能。如果要实现一个控件之间的链结构,我们可以将这些控件之间建立起互相的约束关系,并在这些关系的基础上选择创建水平方向的链还是垂直方向的链。

官方提供了一共有5种样式的链:
在这里插入图片描述

我们可以通过下面的方式设置:

app:layout_constraintHorizontal_chainStyle="spread|spread_inside|packed"
或者
app:layout_constraintVertical_chainStyle="spread|spread_inside|packed"

在这里需要注意的是:在Chain的第一个组件上设置chainStyle,切记 切记

1、属性参数和值

对于Chian属性的种类来说,一共两种:水平方向(Horizontal)和垂直方向(Vertical)

属性描述
app:layout_constraintHorizontal_chainStyle水平方向上的Chain
app:layout_constraintVertical_chainStyle垂直方向上的Chain

对于Chain属性的模式来说,一共三种:展开(spread)、内部展开(spread_inside)、包裹(packed)

2. Spread链模式

spread模式会会把空间平均分配开来,每个View占有各自的平分空间,它是Chain属性的默认模式。

在该模式下,在设置View的宽度和高度为非0dp时,展示效果如下:
在这里插入图片描述
当使用了这个模式的时候,我们还可以配合weight属性设置spread的权重,在设置权重的时候,我们需要将控件的width或者height设置成0dp,并设置layout_constraintHorizontal_weight或者layout_constraintVertical_weight的值:

属性描述
app:layout_constraintVertical_weight垂直方向的控件权重
app:layout_constraintHorizontal_weight水平方向的控件权重

通过权重的设置,如图:
在这里插入图片描述

3. Spread Inside链模式

spread inside模式是在Spread的基础上,把两边最边缘的两个View到外向父组件边缘的距离去除,然后让剩余的Views在剩余的空间内部平分空间。

在该模式下,在设置View的宽度和高度为非0dp时,展示效果如下:
在这里插入图片描述

4、Packed链模式

packed模式很直观,它将所有Views聚拢在一起,控件和控件之间不留间隙,并将聚拢之后的Views居中显示。

在该模式下,在设置View的宽度和高度为非0dp时,展示效果如下:
在这里插入图片描述
当我们使用了Packed模式了之后,我们还可以通过bias参数对聚拢在一起的Views进行位置的调整。
在这里插入图片描述

5、XML中设置Chain示例

设置Chain属性需要保证两个条件:

  • 定义chain链的约束条件
  • 在Chain的第一个组件上设置chainStyle。
<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="match_parent">

    <Button
        android:id="@+id/button16"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintEnd_toStartOf="@+id/button17"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        tools:layout_editor_absoluteY="39dp" />

    <Button
        android:id="@+id/button17"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintEnd_toStartOf="@+id/button18"
        app:layout_constraintStart_toEndOf="@+id/button16"
        tools:layout_editor_absoluteY="39dp" />

    <Button
        android:id="@+id/button18"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button17"
        tools:layout_editor_absoluteY="39dp" />
</android.support.constraint.ConstraintLayout>

6、GuideLine的使用

GuideLine只是用在ConstraintLayout布局里面的一个工具类,用于辅助布局,类似于辅助线,可以设置android:orientation属性来确定是横向还是纵向。
重要的是Guideline是不会显示到界面上的,默认是GONE的。

方向描述
android:orientation方向

创建了GuideLine之后,我们可以设置参考线的初始位置:

权重属性描述
app:layout_constraintGuide_begin以View的起始位置为参照物,水平或垂直方向上边界(dp)
app:layout_constraintGuide_end以View的结束位置为参照物,水平或垂直方向上边界(dp)
app:layout_constraintGuide_percent水平或垂直方向上的百分比(float ratio 0.0f - 1.0f)

总结

整个ConstraintLayout的属性已讲解完毕,使用ConstraintLayout在Android中学习起来吧!

本文转自 blog.csdn.net/klylove/art…,如有侵权,请联系删除。