ConstraintLayout约束布局最全解析
一、ConstraintLayout概述
ConstraintLayout
是Android官方
在2016年Google的I/O大会推出的一种可以灵活控制子控件的位置和大小的新布局方式,也是目前Android的几大布局中功能最强大的布局。在最新版的Android Studio中
,创建布局文件的默认根元素都是ConstraintLayout
了。
ConstraintLayout优点
ConstraintLayout
之所以成为目前Android开发中主流的布局,除了官方建议使用ConstraintLayout外还有以下几个方面的优势
-
功能强大,ConstraintLayout几乎能实现其他布局
所有的功能
-
能减少布局层次的嵌套,有
性能的优势
-
可视化操作的增强,大部分界面用ConstraintLayout都能通过
可视化编辑
区域完成
二、ConstraintLayout基础篇
2.1 基础操作
在Android Studio中默认的布局方式是约束布局,在约束布局中添加控件非常简单,只需要从左侧的Palette
区域拖动控件到中间的界面编辑区域即可。
在约束布局中,点中任意一个控件,该控件的上下左右四个方向各会出现一个圆圈,该圆圈代表可以添加的约束。
当把鼠标移动到圆圈上,按住鼠标左键,然后移动鼠标到父布局的上下左右任意边缘再松开鼠标即可给该方向添加约束,添加完约束后该圆圈会由空心圆变成实心圆,同时控件也会移动到该父布局添加约束的方向的边缘。
当给一个控件上下方向都添加约束后该控件会在垂直方向居中,同样的给一个控件左右方向都添加约束该控件会在水平方向居中。
如果想给一个控件去掉约束,选中该控件后,在右上角Layout
区域,点击该方向上的×
符号即可去掉该方向上的约束
也可以拖动Layout区域
的水平条
和垂直条
来控制左右方向和上下方向两边约束的比例,该值越小,控件会越靠左和上。
给控件某个方向添加约束后该控件默认会紧靠该方向约束的父布局边缘,可以设置控件在Layout区域设置该方向与父布局的边缘间距。
2.2 控件间添加约束
在约束布局中,除了可以给一个控件将约束添加到父布局边缘,也可以将一个控件的约束添加到另外一个控件上,添加约束的方法跟添加都父布局一样。当给一个控件左边添加约束到另外一个控件左边,该控件左边缘会平齐另外一个控件的左边缘。给一个控件的下边缘添加约束到另外一个控件的上边缘,该控件会紧贴另外一个控件的上边缘
如果给一个控件左右两边都添加约束到另外一个控件的两边,这两个控件的大小又不一样,那么该两个控件的中轴线会平齐。
2.3 约束布局xml代码实现
用可视化区域来编写布局虽然比较简单,但是对于一些布局的微调用xml代码会更快,要熟练掌握约束布局,学会用xml代码来编写约束布局也是必备的技能。
给父布局添加约束
app:layout_constraintBottom_toBottomOf="parent"
底部约束app:layout_constraintEnd_toEndOf="parent"
右边约束app:layout_constraintStart_toStartOf="parent"
左边约束app:layout_constraintTop_toTopOf="parent"
顶部约束
这里的Strart和End 换成Left和Right也可以。
将约束添加到其他控件app:layout_constraintBottom_toTopOf="@+id/button3"
底部添加约束到其他控件顶部app:layout_constraintEnd_toEndOf="@+id/button3"
右边添加约束到其他控件右边app:layout_constraintStart_toStartOf="@+id/button3"
左边添加约束到其他控件左边
三、ConstraintLayout 进阶篇
3.1 Chains链
在LinearLayout
布局中weight
属性能够实现子控件讲父布局的控件按比例分配,在ConstraintLayout 中通过Chains链也能够实现相同的功能,而且Chains链的功能比LinearLayout
布局中weight
属性功能更加强大。
Chains链
的基本用法如下:选中多个控件,右键Chains
->Create Horizontal Chains
即可将父布局的剩余空间进行均匀分布。
Chains链
对父控件的剩余空间有三种分配方式,即Spread、spread inside、packed,默认值是Spread即将控件包括第一个控件和最后一个两边均匀分配
spread inside
值表示第一个控件和最后一个控件两边不分配空间
spread inside
值表示所有控件挨在一起,第一个控件和最后一个控件两边均匀分配父控件的剩余空间
3.2 尺寸约束
在其他布局中,控件的尺寸单位有wrap_content
、dp固定值、match_parent
三种值,在约束布局中的控件还可以给其设置MATCH_CONSTRAINT(0dp)
,该值的含义代表约束尺寸,即控件的尺寸由其左右两边的约束来控制。
举个栗子
比如很多app的首页都是由底部banner
和顶部fragment
组成,而fragment的高度通常不是固定的,如果用其他的布局fragment的高度就很难调节,这时候可以用MATCH_CONSTRAINT(0dp)
动态调节fragment的尺寸高度,给顶部的fragment设置其高度为0dp
,给其上下各添加一个约束,这时候其高度为父布局的顶部到底部控件的顶部。
<?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"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/purple_200"
android:text="底部banner"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/teal_200"
android:gravity="center"
android:text="顶部fragment"
app:layout_constraintBottom_toTopOf="@+id/textView4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.3 百分比布局
ConstraintLayout 还支持控件的尺寸按照父布局尺寸的百分比来设置
-
app:layout_constraintWidth_percent 宽度占父布局百分比比例
-
app:layout_constraintHeight_percent 高度占父布局百分比比例
tips:只有宽度和高度尺寸为0dp百分比属性才会生效
3.4 radio属性
有些app的banner图通常是按照一定比例来设置的,如16:9,1:1等,用其他布局图片的宽度如果设置成match_parent,图片的高度就需要根据比例动态去计算,非常的麻烦。在约束布局中通过radio
属性很容易实现这样的需求。
给图片宽度设置match_parent
,高度设置成约束尺寸0dp
,然后再添加一个layout_constraintDimensionRatio
属性,属性的值可以设置h,16:9
其中h表示高宽比的比值,也可以设置成将值设置w,9:16
,w表示宽高比的比值。
3.5 圆形定位
ConstraintLayout 还支持圆型定位
,将一个控件的中心以一定的角度和距离约束到另一个控件的中心上,相当于在一个圆上放置一个控件。
圆形定位主要通过以下三个属性值来控制
-
layout_constraintCircle
:引用另一个控件的 id。 -
layout_constraintCircleRadius
:到另一个控件中心的距离。 -
layout_constraintCircleAngle
:控件的角度(顺时针,0 - 360 度)。
四、ConstraintLayout 高级篇
4.1 Guideline
Guideline
是ConstraintLayout布局里面的一个工具类,其作用相当于一条辅助线,默认不可见,可以用于辅助布局
layout_constraintGuide_percent
:按照比例设置辅助线的位置layout_constraintGuide_begin
:按照值设置辅助线的位置
Guideline辅助线的位置既可以按照百分比来设置,也可以按照值来设置。
4.2 Group
Group 可以对一组的控件同时设置其可见性的值Visible、Invisible或者Gone
。
其使用方法如下:在布局中右键添加Group,再将一组控件拖动到Group中,通过控制Group的属性来调节一组控件的可见性。
4.3 Barrier
Barrier和Guideline 一样,本身不可见,用户辅助布局。
假如有个这样的需求,页面中有个两个Button1和Button2,一个TextView3 ,现在需要让TextView3 处于Button1或Button2的右边,对齐Button1和Button2中较宽的控件。
如果将TextView3 的左边约束的加在Button1上,当Button2较宽时会挡住TextView3 ,在不用Barrier时,需要通过再增加一层布局将Button1和Button2放到布局中才能实现该需求。
使用Barrier的解决方案:
1、首先在编辑区域右键添加一个垂直方向的Barrier,将Button1和Button2拖动到Barrier中
2:将Barrier的barrierDerection
属性设置成right
,right
属性表示其他控件对齐barrier控件中的靠右的控件
3、将textview3左边的约束加到Barrier上
测试效果如下