| 导语 ConstraintLayout是Android Jetpack里引入的全新布局类,可以理解为RelativeLayout+LinearLayout的混合强化版,同时新版Android Studio的布局编辑器也提供了对ConstraintLayout完善的编辑支持。使用ConstraintLayout,可以很方便地在一个层级上实现复杂的布局,功能也很完善,是Android官方目前非常重视的一个Layout(替代以前的RelativeLayout),因此ConstraintLayout值得来探究一番。
ConstraintLayout是Google IO 2016引入的一个全新布局Layout,隶属于Jetpack项目(即包含在androidx包里),目前release最新版本是1.1.3,在build.gradle里添加依赖即可,如下:
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
关于ConstraintLayout的详细用法,可以参考网上的资料和Android官方文档(https://developer.android.google.cn/training/constraint-layout),对着文档操作一番,很容易就上手了。
本篇主要想介绍ConstraintLayout几个强大并且RelativeLayout缺乏的特性,感兴趣的话请往下看。
Constraint即约束,即对一个View的Left(Start),Top,Right(End),Bottom四个方向添加Constraint条件后,此View的位置也就确定下来了,Constraint也是ConstraintLayout最基本的操作。
一个Constraint条件包括源View(即自己)和目标View(其他view或者Parent),具体到XML里是 layout_constraintTop_toTopOf / layout_constraintStart_toEndOf这些属性,和RelativeLayout的layout_toStartOf / layout_toLeftOf非常相似,一般通过Android Studio的可视化编辑器来完成约束的操作。
相比RelativeLayout,ConstraintLayout的Constraint优势主要体现在两个方面,1是完善的可视化编辑支持,2是Constraint结合后面会介绍的Bias/Chain/Barrier等特性,可以更加灵活地布局。
这里简单介绍下Android Studio(3.5)的可视化编辑功能,新版的AS布局编辑器和ConstraintLayout高度集成。
2.1. 创建Constraint
如上图,要为一个View添加约束,先选中它,然后有两种方式:
第一种方式是按住边上的圆点拖动箭头,然后指向要依赖的View上的某条边即可,如(1),Constraint创建成功后会有一条蓝色的折线;
第二种方式是在最右侧的4宫格里点击+按钮添加,AS会添加约束到最近的那个View,如(2),添加成功后,(3)这里可以编辑Margin的值。
一般通过第一种方式添加约束比较方便,(2)这里主要是更新margin等属性的值。
2.2. 快捷操作菜单
如上图,在编辑区右键可以弹出快捷菜单,像一些需要多个View一起操作的选项(比如Align,Chains等),需要同时选中多个View后再右键,才能操作。
值得一提的是,ConstraintLayout不管是概念上还是编辑器设计上,和iOS的AutoLayout都非常的相似,iOS再一次走在了前面^_^,如下图:
RelativeLayout相信大家都可能遇到一个问题,假设ViewA依赖ViewB来定位,如果ViewB被设置成了GONE,ViewA的位置就乱了,相当于约束失效了。
ConstraintLayout对此问题做了兼容处理,假设有如下3个Button,Button3的约束依赖于Button2:
我们把Button2 Visibility设置为GONE,表现如下:
可以看到,ConstraintLayout在此场景下,约束依旧生效!Button2相当于宽高变为0了,但约束还生效。
Bias即偏移值,对应XML里的layout_constraintHorizontal_bias / layout_constraintVertical_bias,取值范围从0到1,默认是0.5,代表是位置偏移比例。
当在某个方向上添加约束后,View默认是居中的(Bias=0.5),如下图:
这时候就可以通过修改Bias的值来移动位置,比如修改成0.2,如下图:
更方便的操作是修改编辑器上的滑块(从0到100,对应XML里的0到1),如下图:
Guideline比较简单,可以理解成一个不可见的View放在ConstraintLayout某个位置,然后子View就可以以他作为Constraint目标来定位。
Barrier意为屏障,和Guideline相似,也是一个不可见的View,但Barrier可以保证一直位于某几个View的Top/Bottom/Left/Right下面,有些场景下可能很有用。
举个例子,如下图,下面的ImageView需要保持在上面一排按钮下方40dp处,简单处理可以添加一个指向Button2下方的约束。
但假设Button3的高度变大了,整体效果就不合预期了,如下:
这时候就可以添加一个Barrier,设置barrierDirection="bottom",而且绑定上面3个Button,ImageView再添加指向Barrier的约束,效果如下,中间那根虚线就是Barrier(用户不可见)。现在不管3个Button高度怎么变化,Barrier都会保持在最下方。
创建Barrier的操作步骤如下:
第一步,创建Barrier,如下:
第二步,完成View的绑定。
在ComponentTree窗口里,直接拖动对应的子View到Barrier里就完成绑定了,如下:
第三步,View添加约束到Barrier。
Chain即为链条,可以实现多个子View按一定的比例并排在一起,ConstraintLayout借助此功能,可以实现LinearLayout大部分效果。
借用官方文档的一张图,如下:
有4种排列方式,也即chainStyle(xml里叫layout_constraintVertical_chainStyle),分别为:
1:Spread
子View居中平均分布,左右间距也平均分割。
2:Spread inside
第一个和最后一个贴边,其他的View平均分布。
3:Weighted
子View按Weighted参数比例分布,和LinearLayout的Weight参数一样。注意的是,本身并不存在叫Weighted的chainStyle,而是在第一种style模式下,子View的宽度设为0,同时设置layout_constraintHorizontal_weight参数就能进行比例划分。
4:Packed
所有子View居中贴在一起。
注意的是,chain并不是说设置一下chainStyle的参数,A,B,C 3个按钮就能如图上一样排在一起,A,B,C本身还是需要通过Constraint约束来排成一排,然后设置第一个View(这里是A)的chainStyle参数,就可以控制A,B,C的排布情况。
可以看到,ConstraintLayout通过chainStyle就可以实现多个View的居中排列, 比较方便,LinearLayout如果要实现如上几个效果,还必须通过添加一些EmptyView辅助来实现。
创建Chain的具体操作如下:
第一步,选择要排成一起的子View,注意,这些子View不要带Constraint,有的话要清除掉Constraint,因为已有的Constraint会影响后续的操作,如下:
第二步,同时选中这些view,右键菜单,创建对应方向的Chain,如下:
创建成功后,可以看到3个View相互之间已经添加了Constraint约束,如下:
第三步,我们需要3个Button顶部对齐,可以再选中3个View,右键菜单,创建Align,如下:
创建成功后,可以发现就是最前面chainStyle=”Spread”的表现了,因为默认的chainStyle就是Spread,如下图:
第四步,可以通过修改第一个View的layout_constraintHorizontal_chainStyle参数,来控制排列样式,具体参照最前面的内容。
总结一下,ConstraintLayout相比RelativeLayout+LinearLayout,优势主要体现在:
1)可以减少层级,性能提高
对于一些复杂的布局,传统做法里,可能root是一个RelativeLayout,对于一些需要比例排布的子View,再嵌套LinearLayout,这样就多了一个层级。而使用ConstraintLayout的话,通过前面介绍的Chain等功能,完全可以在一个ConstraintLayout里实现。层级减少,意味着渲染性能提升,官方的数据是渲染速度比RelativeLayout提高大约40%,可以再研究下。
2)可视化编辑能力完善
最新版的AS布局编辑器,可以说就是和ConstraintLayout高度集成的,以前我们在编辑器里更多可能是编辑属性的值,但ConstraintLayout的约束和元素定位,利用可视化编辑器,可以大大地提高开发效率。
3)实用的新特性
ConstraintLayout增加了Bias/Guideline/Barrier等额外新特性,相比传统做法里需要代码判断等方式,可以说简化了开发者的逻辑,只需要XML里配置即可完成。
与此同时,ConstraintLayout也存在一些劣势,比如说有一定的熟悉成本,涉及的概念比较多,xml可能会比较复杂和繁乱(借助可视化编辑器可以不需要关心xml内容),也可能存在一些未知的bug。
总体来看,ConstraintLayout是Android官方很重视且逐步在推广的一个标准布局,而且和iOS的AutoLayout布局方式也很相似,相信有比较光明的未来!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。