该篇文章的主旨是帮助开发者了解ConstraintLayout的基本使用方法以及在平常开发项目中的使用场景的说明android
ConstraintLayout是一个ViewGroup,容许你灵活的指定子View的位置和大小(具体多灵活在下面的场景中进行说明),官方文档中说明ConstraintLayout的特性有如下几种:bash
以上几个特性部分有点抽象,官方文档中也对每个特性都进行了详细的说明和举例,有意者能够单独去查阅,ConstraintLayout , 在下面的应用场景中也会穿插说明。对于开发者来讲,主要了解使用场景和在项目中如何使用,用得多了就对该控件有了比较深刻的了解。再看文档会更容易理解。毕竟文档是英文的。app
在没有ConstraintLayout以前咱们写布局通常使用到的布局就是相对布局和线性布局,相对布局中控件的位置都是基于另外一个控件的位置,这个和ConstraintLayout有一丝类似之处,线性布局就是直接以瀑布流的形式进行布局。ConstraintLayout根据字面意思了解为约束布局,因此,因此在写布局文件的时候,须要对每个控件进行约束 ,对每个显示在约束布局中的内容进行约束,约束其大小,位置。下面介绍一下约束布局的相关属性和使用。ide
决定视图的大小和位置能够由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>
复制代码
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,这样控件就直接居中了。 设计
该约束是针对文本相关控件添加的,好比要再添加一个注册按钮在登陆的右侧
<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" />
复制代码
在上面的基线约束中,可能你会发现登陆和注册的位置很是对称,这个就是chains约束,对于chains约束只说明两点,你就会轻松使用了。
例如上面的登陆和注册两个按钮,登陆的右边距约束必须添加到注册的左边距上,即:登陆的 end_ToStartOf="btn_sign_up",注册的 start_toEndOf="btn_login",若是是多个控件同样,一个控件的结束依赖到另外一个的开始。这是水平chain , 垂直的桶里
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"
/>
复制代码
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"
/>
复制代码
可见性行为的属性包括:
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也是一个控件,可是这个控件是只在约束布局中才能起做用的辅助控件 ,是帮助辅助布局的,好比说,咱们添加一个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" />
复制代码
以上几方面就是在平常开发中的基础使用相关介绍,掌握了这些基本上都能知足开发的需求,下面说下ConstraintLayout的使用场景
之前咱们在实现布局的时候常常各类嵌套,如今不带滚动的布局,均可以只用一个父布局就能够解决,减小了布局的层级深度
在NestedScrollView中嵌套一个ConstraintLayout便可。
之前item布局也是各类嵌套布局,有了ConstraintLayout以后发现真的是省事了不少,代码看起来也比较舒服
像有一些banner图的设计尺寸都是固定的,咱们只须要宽度设置全屏,而后设置宽高比,就能适配全部屏幕,等等。。妙用不少,实际开发本身发掘。
总之若是在使用ConstraintLayout看了该内容哪里不对但愿评论补充,或者不对的地方纠正我一下,若是是没有用过的,但愿你赶忙用起来,省时省力