Android控件之ConstraintLayout

目录:

1、为什么要用ConstraintLayout?
2、ConstraintLayout有哪些缺点?
3、怎么使用ConstraintLayout。

1、为什么要用ConstraintLayout?

  • 任何复杂的布局只需一层(除非有嵌套的事件响应需求):

绘制过程中的每个阶段都需要对视图树执行一次自顶向下的遍历操作。因此,视图层次结构中嵌入(或嵌套)的视图越多,设备绘制视图所需的时间和计算功耗也就越多。通过在 Android 应用布局中保持扁平的层次结构,您可以为应用创建响应快速而灵敏的界面。

  • 性能更出色

ConstraintLayout 在测量/布局阶段的性能比 RelativeLayout大约高 40%。
详情参阅:解析ConstraintLayout的性能优势

  • LinearLayout和RecyclerView的布局能做到的ConstraintLayout都能做到,它们做不到的也能做到(这一点后面详解)。

2、它有哪些缺点?

  • xml很啰嗦

主要体现在两方面:
1、它需要通过详尽的属性来确定自身位置,因为以前用LL或RL的写法,有些属性在父容器写一次就够,子容器就无需再写一次,但这个是每个容器都是独立的,需要根据周围的控件确定自身的位置。所以这就引出了第二个啰嗦。
2、每个View都要有与之对应的id。

  • 没有gravity属性,这里后面会讲到一个“拉力”的概念,这里先简单说一下,怎么实现gravity=center这样的效果呢?需要把每个边都与父容器的边对应上(需设置4个属性),因为四个边都要拉扯以将控件拉到中间。

3、怎么使用?

1、引入资源
compile 'com.android.support.constraint:constraint-layout:1.0.2'
2、熟悉它的属性,主要有几部分:
part1:类似于RelativeLayout的部分:

根据其他控件给自身定位:

layout_toRightOf="A"——>layout_constraintLeft_toRightOf="A"

根据父容器给自身定位:

layout_alignParentRight=true——>layout_constraintRight_toRightOf=parent

类似的还有:

layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
//根据某控件的基线对齐
layout_constraintBaseline_toBaselineOf

part2:类似LinearLayout的weight效果

官方有张图,如[图1]所示,通常来说,LinearLayout的weight只能实现第四行的效果,但ConstraintLayout可以实现下图全部。

Android控件之ConstraintLayout_第1张图片
图1

想实现类似LL(LinearLayout)的weight的效果,重点看每个TextView的最下三行以及每个TextView的 layout_width都是0,以下布局可以实现三个TextView。








如果想实现2:1:1等分的效果,就如[图1]的第四行,需要给每个TextView分别添加如下属性,并挨个设置值为2,1,1即可:

app:layout_constraintHorizontal_weight
part3:以下是LinearLayout和RelativeLayout都做不到的,或者说是[要花很大的代价才能实现]这种表达是不是更准确点?
1、先说一下【链(Chains)】的概念:

ConstraintLayout中的控件想要定位准确,A控件是要依赖于父容器左侧和B,然后B控件依赖于A和B,C依赖于B以及父容器的右侧,就如图2所示:

Android控件之ConstraintLayout_第2张图片
图2.png

这个链代表了某种约束和拉力,上图A,B,C之间存有间隙,(ps:如果要间隙等分的话,需设置layout_width=0dp),图2每个控件拉力都是一样的,如果想实现[图1]的其他效果,实际上都是根据拉力大小变化来实现的,B拉力大一点,那A和C都更靠近B一点点,类似这样的道理。

这里要引出一个属性:

layout_constraintHorizontal_chainStyle

该属性有三个值:spread(铺开),spread_inside(里面铺开), packed(拥挤),效果依次对应图1的:第1行,第2行,第4行。
默认是spread。(ps:以上效果layout_width是固定值或wrap_content,如果是0的话就会类似第3行那样)


Android控件之ConstraintLayout_第3张图片
图1
2、用bias(偏斜)实现[图1]第5行的效果

简而言之就是调整C控件两边的拉力即可,对应的属性是:

layout_constraintHorizontal_bias //水平线的拉力
layout_constraintVertical_bias  //垂直线的拉力

该属性的值是0~1,默认是0.5,通过调整水平线的拉力即可达到第5行的效果了。

3、控件的宽高比

以前如果想要实现一个Banner宽高比是2:1这样的,很麻烦,因为每个机型分辨率有大有小,除非代码运行才能知道屏幕宽度是多少,才能动态得到屏幕宽度,在xml中根本无法实现。
但ConstraintLayout提供了一个属性就能实现:

app:layout_constraintDimensionRatio="W,2:1"
或
app:layout_constraintDimensionRatio="H,1:2"

注意:宽高需要设置0dp才能有效果!

part4:关于Guideline(辅助线)

这个是为了方便ConstraintLayout布局,如果用过CAD的朋友就应该知道辅助线,用来辅助画图很方便,而且保存文件的时候该线是不会显示到图片上的,同理,这个也只是在写xml的时候辅助用的,应用真正运行的时候是看不到的。

因为是一条线嘛,自然要区分水平还是垂直的,所以就有一个属性:

android:orientation

取值为”vertical”和”horizontal”,跟RecyclerView一样。

它还有一些属性用来给辅助线找准位置,然后给辅助线命名个id,其他控件只要基于该先找到自己的位置就好啦~

layout_constraintGuide_begin  
layout_constraintGuide_end
layout_constraintGuide_percent

它有两种方式来找到自己的位置,一个是绝对值,也就是begin&end(取值为dp),一个是百分比percent(取值为0~1)。
当orientation为vertical的时候,begin对应距离顶部,end对应距离底部。
当orientation为horizontal的时候,begin对应距离左边,end对应距离右边。

真正使用的时候,就把Guideline当作一个View来用好了,Android Studio也会有预览给你看的,记得要给它命名啊,不然其他控件怎么基于它定位呢,对吧?


更多请参阅:

1、鸿洋:ConstraintLayout 完全解析 快来优化你的布局吧
2、郭霖:Android新特性介绍,ConstraintLayout完全解析
3、Google官方文档——ConstraintLayout
4、Google官方文档——Guideline
5、解析ConstraintLayout的性能优势

你可能感兴趣的:(Android控件之ConstraintLayout)