ConstraintLayout的使用教程

该篇文章的主旨是帮助开发者了解ConstraintLayout的基本使用方法以及在平常开发项目中的使用场景的说明android

ConstraintLayout官方文档

ConstraintLayout是一个ViewGroup,容许你灵活的指定子View的位置和大小(具体多灵活在下面的场景中进行说明),官方文档中说明ConstraintLayout的特性有如下几种:bash

  • Relative positioning - 相对位置
  • Margins - 边距
  • Centering positioning - 位置居中
  • Visibility behavior - 可见性行为
  • Dimension constraints - 尺寸限制
  • Chains - 链
  • Virtual Helpers objects - 虚拟帮助对象(Guideline)
  • Optimizer - 优化

以上几个特性部分有点抽象,官方文档中也对每个特性都进行了详细的说明和举例,有意者能够单独去查阅,ConstraintLayout , 在下面的应用场景中也会穿插说明。对于开发者来讲,主要了解使用场景和在项目中如何使用,用得多了就对该控件有了比较深刻的了解。再看文档会更容易理解。毕竟文档是英文的。app

使用说明

在没有ConstraintLayout以前咱们写布局通常使用到的布局就是相对布局线性布局,相对布局中控件的位置都是基于另外一个控件的位置,这个和ConstraintLayout有一丝类似之处,线性布局就是直接以瀑布流的形式进行布局。ConstraintLayout根据字面意思了解为约束布局,因此,因此在写布局文件的时候,须要对每个控件进行约束 ,对每个显示在约束布局中的内容进行约束,约束其大小,位置。下面介绍一下约束布局的相关属性和使用。ide

ConstraintLayout的基本属性

决定视图的大小和位置能够由View四个边来肯定,left top right bottom, 因此约束布局能够经过对四个边的约束来达到实际布局效果,相关四个边的属性有,如:布局

app:layout_constraintLeft_toLeftOf
app:layout_constraintLeft_toRightOf
app:layout_constraintRight_toLeftOf
app:layout_constraintRight_toRightOf
app:layout_constraintTop_toTopOf
app:layout_constraintTop_toBottomOf
app:layout_constraintBottom_toTopOf
app:layout_constraintBottom_toBottomOf
app:layout_constraintStart_toEndOf
app:layout_constraintStart_toStartOf
app:layout_constraintEnd_toStartOf
app:layout_constraintEnd_toEndOf
复制代码

应该根据这些属性的名称就能了解它们的做用,下面举例说明:好比实现一个登录界面,两个文本框和一个按钮。优化

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <EditText
        android:id="@+id/edt_username"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="25dp"
        android:layout_marginTop="200dp"
        android:layout_marginEnd="25dp"
        android:hint="请输入用户名"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/edt_password"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:hint="请输入密码"
        android:inputType="textPassword"
        app:layout_constraintEnd_toEndOf="@id/edt_username"
        app:layout_constraintStart_toStartOf="@id/edt_username"
        app:layout_constraintTop_toBottomOf="@id/edt_username" />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="登 录"
        app:layout_constraintEnd_toEndOf="@id/edt_password"
        app:layout_constraintStart_toStartOf="@id/edt_password"
        app:layout_constraintTop_toBottomOf="@id/edt_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
复制代码

很简单的一个页面,若是用LinearLayout更快,可是ConstraintLayout自己就是为了解决复杂布局而生的,在平常开发中的需求可能会让你各类嵌套布局,可是ConstraintLayout基本上都是一个布局就能够ok,因此只有你了解后才知道使用有多得劲,如今简单的分析说明下上面的布局原理。

1.肯定用户名EditText的位置和大小,从四个边来约束,首先约束top,使用top_toTopOf="parent"将用户名EditText的顶部和父布局的顶部关联起来,而后经过marginTop来增长边距,若是不设置top_toTopOf属性,marginTop属性是不起做用的,任何没有增长约束的设置margin属性都是不起做用的,上面的代码中咱们将EditText的width设置为0dp,而后给左右两边分别增长了约束,约束到父布局的start和end,经过以上三个属性,就肯定了该EditText的位置和大小。ui

2.肯定了用户名EditText的位置以后,进行添加密码EditText,和上一个EditText相似,增长左右上三边的约束,不一样的是top_toTopOf属性的值改成了edt_username,不在把约束添加到parent,而是添加到用户名的EditText,这样密码EditText就显示到用户名的下面了。登陆同理加密

只须要记住,ConstraintLayout中的全部空间添加上 左上右下 四个边的约束,就能肯定空间的位置(对应了开始说的 Relative positioning 和 Margins 两个特性) ,记住这个就掌握使用的一大半了spa

控件居中

想让控件居中也很简单,好比说上面的登陆按钮,不想要那么大,能够将控件的width属性改为wrap_content,这样控件就直接居中了。 设计

在给控件添加完约束以后,若是width或者height给的值为0,则控件的大小将彻底按照约束的大小进行展现,若是设置了wrap_content,则控件会居中显示

基线对齐约束

该约束是针对文本相关控件添加的,好比要再添加一个注册按钮在登陆的右侧

<Button
        android:id="@+id/btn_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="登 录"
        app:layout_constraintEnd_toStartOf="@id/btn_sign_up"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="@id/edt_password"
        app:layout_constraintTop_toBottomOf="@id/edt_password" />

    <Button
        android:id="@+id/btn_sign_up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="注册"
        app:layout_constraintBaseline_toBaselineOf="@id/btn_login"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toEndOf="@id/btn_login"
        app:layout_constraintEnd_toEndOf="@id/edt_password"
        app:layout_constraintTop_toBottomOf="@id/edt_password" />
复制代码

在上面的注册控件中,增长了layout_constraintBaseline_toBaselineOf属性,依赖登陆按钮,这样他们的绘制基线就在同一y轴上了,从而达到对齐的效果。

Chains

在上面的基线约束中,可能你会发现登陆和注册的位置很是对称,这个就是chains约束,对于chains约束只说明两点,你就会轻松使用了。

  • 控件之间要相互依赖。

例如上面的登陆和注册两个按钮,登陆的右边距约束必须添加到注册的左边距上,即:登陆的 end_ToStartOf="btn_sign_up",注册的 start_toEndOf="btn_login",若是是多个控件同样,一个控件的结束依赖到另外一个的开始。这是水平chain , 垂直的桶里

  • 添加chain属性 待须要增长chain约束的控件都依赖完了以后,就须要给每一个控件增长chain属性了,即:layout_constraintHorizontal_chainStyle 或者 layout_constraintVertical_chainStyle , 该属性能够有多个值,分别对应的效果借鉴官方文档的,以下:

Dimension constraints - 尺寸约束

layout_constraintDimensionRatio

尺寸约束的使用很少,可是这个属性很重要,在不少的场景中可使用该约束,先对属性进行说明,应用场景后面再说。了解了做用,天然就能在实际开发中找到场景。好比说咱们要实现一个ImageView的宽是高的2倍,可能有人想,我把宽固定了那高除以2不就出来了嘛,固然能够,可是有些场景,好比说宽是屏幕的宽度,match_parent呢,用尺寸约束就能够很轻松的达到效果。

<ImageView
        android:layout_width="0dp"
        android:layout_height="0dp" 
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintDimensionRatio="2:1"
        android:background="@color/colorAccent"
        />
复制代码

这样就比较轻松的实现了高是宽的2倍,在什么机型上都是。

百分比约束

layout_constraintHeight_percent

layout_constraintWidth_percent

分别对宽高进行百分比约束。

<ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHeight_percent="0.2"
        app:layout_constraintWidth_percent="0.5"
        android:background="@color/colorAccent"
        />
复制代码

百分比约束相对很实用,可是比较少用,很相似以前LinearLayout的weight权重。

Visibility behavior

可见性行为的属性包括:

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
复制代码

好比说上面的登陆页面,若是程序中设置了用户名EditText设置了setVisible(false),那么密码EditText就会直接到顶部了,甚至形成布局错乱,为何?应为密码EditText的左右约束添加到了用户名的EditText上,若是想让用户名EditText隐藏的时候密码EditText和top右边距,就能够给密码EditText加上goneMarginTop属性,为了防止由于控件隐藏形成布局错乱,在已知一些控件会隐藏的前提下,其余的控件不要左右边依赖可能会隐藏的视图,防止布局错乱 好比上面的为了防止用户名EditText隐藏形成密码EditText显示不了的问题,能够给密码EditText的左右依赖添加到父布局便可。

Guideline - Virtual Helpers objects

guideline也是一个控件,可是这个控件是只在约束布局中才能起做用的辅助控件 ,是帮助辅助布局的,好比说,咱们添加一个GuideLine,将屏幕平分为两半,一个视图在左,一个在右。拿上面的登陆注册两个按钮来讲,上面的实现方式是增长了chain约束,也能够用GuideLine来实现。代码以下:

<androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="登 录"
        app:layout_constraintEnd_toStartOf="@id/guideline"
        app:layout_constraintStart_toStartOf="@id/edt_password"
        app:layout_constraintTop_toBottomOf="@id/edt_password" />

    <Button
        android:id="@+id/btn_sign_up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="注册"
        app:layout_constraintBaseline_toBaselineOf="@id/btn_login"
        app:layout_constraintEnd_toEndOf="@id/edt_password"
        app:layout_constraintStart_toEndOf="@id/guideline" />
复制代码

中间的虚线,即为增长的辅助GuideLine控件,该控件须要设置两个属性,第一是设置orientation属性,垂直或者水平,第二是百分比 layout_constraintGuide_percent,添加好辅助视图以后,其余控件就能够依赖于它进行布局。

以上几方面就是在平常开发中的基础使用相关介绍,掌握了这些基本上都能知足开发的需求,下面说下ConstraintLayout的使用场景

使用场景

  • 不带滚动的复杂布局

之前咱们在实现布局的时候常常各类嵌套,如今不带滚动的布局,均可以只用一个父布局就能够解决,减小了布局的层级深度

  • 带滚动的复杂布局

在NestedScrollView中嵌套一个ConstraintLayout便可。

  • RecyclerView的item布局

之前item布局也是各类嵌套布局,有了ConstraintLayout以后发现真的是省事了不少,代码看起来也比较舒服

  • 尺寸约束和百分比的巧用

像有一些banner图的设计尺寸都是固定的,咱们只须要宽度设置全屏,而后设置宽高比,就能适配全部屏幕,等等。。妙用不少,实际开发本身发掘。

总之若是在使用ConstraintLayout看了该内容哪里不对但愿评论补充,或者不对的地方纠正我一下,若是是没有用过的,但愿你赶忙用起来,省时省力

相关文章
相关标签/搜索