升级Android studio到2.3版本之后,发现新建Activity或fragment时,xml布局默认布局由RelativeLayout更改为ConstraintLayout了,既然已经推荐使用ConstraintLayout,学会怎样使用就很有必要了。本文的主要是目标是:图文结合,讲讲怎样使用ConstraintLayout。
引入ConstraintLayout
为了使用ConstraintLayout,需要在app/build.gradle文件中添加相应依赖:
dependencies { compile com.android.support.constraint:constraint-layout:1.0.1}
此前ConstraintLayout依赖库版本号都带有beta字眼,现在已经推出正式版本1.0.1。当然使用AS新建activity时,AS会自动添加这行依赖的。
创建ConstraintLayout
新建ConstraintLayout布局文件后,打开如图所示:
虽然ConstraintLayout和RelativeLayout等都是ViewGroup的子类,但RelativeLayout,FrameLayout等是位于widget包下的,ConstraintLayout则是在Support包下的。点击界面左下角的“Design”和“Text”可以切换显示视图,“Design”视图是可视化视图,提供拖拽等功能实现界面布局;“Text”视图是通过编写xml代码实现界面布局。
对于传统布局,大部分开发者都是通过编写xml代码来现实布局的,显得“Design”这个可视化工具相当的鸡肋。但对于ConstraintLayout来说,却很适合使用这个可视化工具来实现布局,今天将使用“Design”视图来说明ConstraintLayout的使用。先来观察“Design”视图,
左侧区域是预设的控件集合,顶部区域是操作栏位,右侧区域则是预览作用。
基本操作
界面转换
如果布局不是ConstraintLayout,可以通过下图操作进行转换:
如果转换前的界面是嵌套的,你可以选择一层一层转换,也可以选择在根目录转换。使用的时候,发现这个转换功能并不是很强大,不能确保转换后界面保持一致。
添加控件
如果想添加一个Button,只需从左侧的Palette区域拖拽到预览区域就可以了。拖拽完成后,会在布局中自动生成相应的xml代码。“Design”工具是通过自动生成代码来实现布局的,本质上还是通过xml实现布局。两者是相互联系的,其中一个发生改变,另一个会对应改变。下图,添加一个Button:
通过拖拽,现在已经添加了一个Button。可以在“Text”视图中看到,自动生成了xml代码。虽然添加了Button,但由于还没有给这个Button添加约束,所以在“Text”视图下,可以看到Android Studio报错了:没有为view添加约束,但依然允许运行。由于没有约束,Button并不知道自己所处的位置,实际运行效果和预览效果是不一样的,Button会出现在左上角。如果拖拽Button后,发现Button已经有约束,那么肯定是打开了AutoConnect开关,这个下文再详说。
添加约束
选中Button,能在上下左右看到四个空心小圆圈,把鼠标移动到小圆圈上,小圆圈会变成绿色。这四个小圆圈就是用来给Button添加约束的,实际上所有控件view都有这样的4个小圆圈。现在给Button左边和右边各添加一个约束,如下图所示:
只需选中小圆圈然后拖动鼠标到父布局边框即可成功添加约束。上图中,左侧的预览图叫“Design”,右侧蓝色的视图叫“Blueprint”,添加约束的操作在任意一个视图上都可以完成。
上面的约束是控件到父布局的约束,控件和控件间的约束也是类似。现在再添加一个Button,这个Button在上一个Button的下方,间距86dp(随便给的),如下图:
删除约束
删除控件的约束有多种方式:
1.删除整个布局的约束,如下图:
2.删除某一控件的所有约束:选中该控件,右键,选择“Clear all Constraints”;或者,选中该控件,点击左下角的X符号;当然如果你整个控件都删除了,与之相关的约束也同时被删除了。如下图:
3.删除某个控件的某个约束:选中该控件后,会在控件的上下左右显示小圆圈,把鼠标移到小圆圈上,如果没有约束,小圆圈是绿色的;如果已经存在约束(每个小圆圈有且仅有一个约束),小圆圈是红色的,点击变红的小圆圈就能删除对应的约束了;或者从小红圈重新拖拽一个新约束,也会替换掉旧约束。如下图:
查看控件属性
选中对应的控件,点击右侧的“Properties”,打开属性面板,如下图
默认显示较为常用的属性,如果需要显示更多属性,滚动到底部,点击View all properties查看所有的属性。不确定这里能否囊括了所有的属性值,如果找不到,那只能通过xml编写了囖。至于修改控件属性,直接在该面板上修改即可。
下面重点关注属性面板上的 Inspector视图,如下图:
先说说较为直白的地方:
1.ID栏:这里填写的id就是标识view的ID;
2.layout_width和layout_height:描述控件大小的,可以直接填写数值决定大小,也可以选择wrap_content或match_parent(这两个选项,下面细说),还可以直接拖动来决定控件的大小,如下图:
新增一个Button,给上下左右添加上约束,此时,Button默认居中显示,选中该Button,查看它的inspector,如下图所示:
观察红色框内的两条轴,一条是垂直显示的,一条是水平显示,这两条轴是用于确定Button位置的。现在Button是居中显示,相应地可以看到这两条轴上标识的数值都是50,如果拖动Button,可以看到相应的数值会发生变化。例如,水平向右拖动Button,水平轴上的数值会随之变大(值的范围在0-100之间);按住水平轴上的数字进行拖动,能在水平方向上改变Button的位置。
现在将水平轴移到到最右边,数值为100,观察预览图:
尽管已经移动到最右边了,但发现Button离最右边还是有间距。这是因为生产约束时,系统默认设置了8dp的间距(margin),如红色框所示。可以点击右边红色框内的数字修改间距。观察预览图,发现每个约束上都有直线和波浪线。其中直线表示的是间距(margin),波浪线则相当是上面提到的水平轴或垂直轴,在这里拖动,用于改变Button的百分比位置。
每次添加约束都自动添加一个间距的话,也是挺烦,点击下图的红色框位置可以这样把它干掉:
控件的size
上面提到了Button的layout_width和layout_height,和传统布局相似,有三种:固定值、
wrap_content和match_parent,如下图所示:
1.<<< 图案表示 wrap_content;
2.|-----| 图案表示 固定值;
3.波浪线图案表示 match_parent,这里的match_parent和在RelativeLayout下的match_parent不同,RelativeLayout下的match_parent是用于填充满当前控件的父布局,而这里的match_parent是用于填充满当前控件的约束规则。假设将layout_width设置为match_parent,那么在水平方向上,不能再移动控件,也就是上面说的水平轴移动不再生效,预览图中,控件充满约束规则。
当layout_width或layout_height设置为match_parent时,右上角会出现一个小三角,如下图:
这个小三角的作用是:切换纵横比约束,简单来说就是设置宽高的比例!如下图:
如果通过小三角设置纵横比约束后,再通过手动更改宽高数值,那后者将覆盖前者。
有了基本的了解后,我们来看看一些复杂点的场景。
对齐
对齐约束
实现两个Button左对齐:添加两个Button,一上一下,从Button A添加约束到Button B,如下图操作添加对齐约束:
或者使用Align进行对齐:选中所要对齐的控件,点击Align,最后选中对齐的方式即可,如下图操作:
从Button A添加左对齐约束到Button B后,我们发现,Button A将在水平方向上跟随Button B移动。
除了这种对齐方式外,Android studio还提供了Guideline和Baseline对齐方式!
考虑下面的场景:假如现在有两个Button,一上一下,水平方向都距离距离左边30%,如下图:
按照我们上面所说的,应该这样实现:将两个Button的水平轴数值设置为30即可。但现在我想同时让这两个按钮距离左边40%(原来是30%),或者改为距离右边40%。按照原来的做法,只能一个一个挨着去修改约束,有没有更好的实现方式呢? Guideline应运而生。
Guideline
添加Guideline,如图:
Guideline有两种,一种是垂直方向的,一种是水平方向的,现在观察一下Guideline,如下图:
选中guideline,显示一条虚线,顶部可以看到一个向左的箭头,下方有一个数字(假设是80),
表示:距离父布局左边80dp;点击顶部箭头,发现箭头向右了,下方有一个数字(假设是300),表示:距离父布局右边300dp;再次点击顶部箭头,发现箭头变成了%符号,下方有一个百分比数字(假设是20%),表示在父布局水平方向20%的位置。我们可以拖动guideline更改数值。
guideline的作用
简单来说就是辅助控件确定位置的辅助线!
那怎样实现上面提到的功能呢?先添加一个垂直guideline,再添加两个Button,分别设置按钮右侧到guideline的约束,如下图:
这样,拖动guideline,两个Button都会随着移动了。
现在我们实现了不同控件以guideline为基准,随guideline移动而移动。那怎样实现一个控件随另一个控件移动而移动呢, Baseline登场啦!
Baseline
添加Baseline
选中Button,点击下方的
,就为view添加了baseline,如下图:
为两个Button添加Baseline约束
拖入两个Button,选中Button A,添加Baseline后,拖拽到Button B即可,如下图:
每个控件的baseline只有一个,从Button A拖拽到Button B,B会自动生成baseline,现在两个button已经建立baseline约束了。我们发现,Button A只能水平方向上拖动,垂直方向上无法拖动;Button B可以水平拖动,也可以垂直拖动,而且在垂直方向上移动时,Button A也会随之移动。由A到B添加了baseline,意味着A在垂直方向上的位置只能由B来决定了,这就是Baseline的对齐作用。
自动添加约束
添加自动约束的方式有两种:一个是Autoconnect
另一个是Infer Constraints
1.Autoconnect默认是关闭的,开启后,添加控件时,Android
studio会检测用户的意图,自动为控件添加约束。比如,拖动一个Button到预览图水平居中的位置,AS检测出可能是希望居中,就会显示一条虚线,这时松开Button,就会自动为Button添加约束,如下图所示:
注意只有AS检测出用户意图后(即预览图中出现虚线),才会自动添加约束,否则也不会有约束。
2.Infer Constraints和Autoconnect功能相似,但比后者更强大。Autoconnect是自动为正在操作的控件添加约束,而infer Constraints则是自动为整个布局内的控件添加约束。适用于较复杂的界面,为这样的界面一键生成约束!
需要注意的是:通过这两种方式自动添加的约束不一定符合要求,这时候手动修改就行了。
为自定义的控件添加约束
Design界面运行拖动的控件都是系统预设的控件,对于自定义的控件怎么办呢?
找不到可以直接将自定义控件拖进面板的操作,可以先对一个基础控件(如Button)进行约束,然后再更改xml代码,将自定义控件替换该Button。对于自定义的属性也需要手动编写xml代码。