谷歌在2016年的IO大会上推出的一种新的布局方式—-ConstraintLayout,这局是一种约束型的布局方式。在设置和介绍上类似IOS的自动布局。
先放上Google的官方解析地址:点击链接 ,虽然这个地址我从来没进去过,现在另外附上一份这个官方Demo的Github地址,git: https://github.com/googlecodelabs/constraint-layout.git
如果在Android studio中不会使用github,还是去找找相关资料了,毕竟这部分技能应该算的上是程序员必备了。
那么,从下面开始详细介绍ConstraintLayout这个布局的使用。
1.准备
第一步,工欲善其事
首先先装上Android studio的新版,不要求是最新版,但一定是要超过2.2的版本,截止本文结束前,当前版本是2.2preview6。如果打算升级,但现在是2.1.2等稳定版,则选择更新,
选择Update dialog of your IDE settings.
在这里选择DEV版本。
虽然肯定不会升级成功,下面直接附上下载地址(PS:官方网址,需要翻墙),官方下载地址,如果由于种种原因无法翻墙的基友们请看此处,百度云下载。
第二步,必先利其器
理所当前,使用新的布局方式首先应该导包,ConstraintLayout所在的文件是android.support.constraint.ConstraintLayout,而这个文件在(箭头所指)
使用Library Dependency可以直接导入。不明白Maven,Gradle等配置的童鞋,建议去找一些资料看,毕竟这在以后的开发中还是挺重要的。
到了这一步终于可以使用ConstraintLayout这种布局方式了。
在实际操作前先说一下他的性质。
先看ConstraintLayout作为一个ViewGroup的子类,而他并没有没有重载onDraw的方法,他的onLayout()方法也非常简单,
可以看出所以源码中,他内部的子view都是以相对关系存在的,所以只要计算出子view的坐标,就能推算出其他childview该放在布局哪个位置。所以在他的layout的过程也十分简单。
对于他的OnMeasure()方法,有兴趣的同学可以去看看。另外附上一张RelativeLayout的布局,同样继承于ViewGroup,在他的onLayout()方法中,见下图:
可以差不多的看出ConstraintLayout与RelativeLayout对于子控件的排列方式差不多,可以将ConstraintLayout理解为RelativeLayout的升级版(我也不知道这个名称是否得当,欢迎斧正)。
可以将ConstraintLayout当做RelativaLayout的布局使用,以及对于子控件的摆放,各位童鞋都有一些印象了吧。
、
2.约束性关系
在这个布局中,最为关键重要的就是约束性关系这个概念。
我的表达能力不是很好,童鞋们理解就好,不理解的话请参考关系数据库完整性约束(大概意思)。
约束性关系帮助你保持子控件与子控件对齐或者存在相互的关系. 你可以使用锚点来约定子控件之间存在何种对齐方式。如下图的ButtonA与ButtonB。我们从ButtonA的锚点指向ButtonB,并约束了96dp的间距,则此时移动ButtonB则会与ButtonA保持96dp的距离,而且在移动时的ButtonA也会移动。而操作ButtonA则是很随意,这就是约束性的关系,ButtonA约束了ButtonB的行为。
下图是动态操作,表述上文所述的一些行为。
下面介绍一下完整的整体的各个含义:
其中四个角的位置可以将控件缩放的操作点,而在四个边上的圆圈是锚点,(PS:锚点是对应的,上下的锚点只能和上下行的锚点链接,不能和左右的锚点链接),中间的椭圆形式句柄(?),这个的作用是将水平方向的控件内部的字体水平对齐。
下图详见操作(有一些操作现在没有讲到,比如自动对齐,这个将会在下面讲):
3.正文
上面的内容只是ConstraintLayout布局的一些基础知识点,现在我们来正式的看ConstraintLayout的使用。
我们先把一张图片附在布局中,成像效果如下:
一些初学者会以为右侧的波浪线是图片的黑白平衡,通道,色差之类的,但很抱歉,什么也不是,是Android studio的布局中加载图片的一种显示方式。就像Button控件中有一个句柄一样,图片并没有这个东西。
现在我们把眼光移向右上角,会发现出现了一个2字,
,打开这个2(这个是错误的个数)会发现里面报了若干个(2个)错误(警告),下面来给大家讲解一下这些都是什么含义。
其中第一个是:此子控件缺少约束,否则按左上角(0,0)的位置进行判断子控件的位置,这个错误在Relativelayout布局非常常见,可以不必理会。
在这里比较关键的是第二个警告,此控件缺少contentDescription这个节点,而这个节点同样也是新增的内容,是Android新版新增添的功能-无障碍阅读的一种实现。
对于Android新增的无障碍阅读功能在系统设置-无障碍里面(由于国产ROM的百花齐放,这个功能自己摸索去),这个功能的主要作用是给一些视力障碍的群体正常的使用Android系统,在触摸某些设置的控件时会发出提示音(使用Google提供的Talk软件)。而这个的操作就是依靠contentDescription这个新属性。添加地点在:
点开之后是选择value,在@string/XXX下面,启动无障碍模式,会播报在此处选择的文字。
现在又出现一个新的面板-Properties,是对新功能的补充,如果大家还是怀念原来的样式,则打开方式是:右上角的
左右箭头的符号,顿时就有爱了,还是原来的配方,还是原来的味道。
好了,扯了这么多闲话,现在正是创建约束性的操作,在通过上面的学习,相信大家对这个约束性的关系和创建约束肯定很感兴趣。
1. 手工创建约束性的操作
容我先创建两个可亲可爱的按钮(Button),点击A Button右侧的圆圈,右侧的圆圈会出现类似呼吸灯的状态,点住按钮会出现一个箭头,将箭头想右引导,如果成功A Button会移动到B Button的旁边,而且A Button的呼吸灯变成红色(?原谅我没看出来)。到这步就手工创建好了两者的约束,可以自由操作了。
具体操作如下:
这是两个控件中的手工创建约束,下面是单个控件与上层布局的约束。
这种方式比较好的地方在于可以与左右上下限定所谓的位置,类型LinearLayout的百分比的方式,
在代码中的体现是:
比较好的融合了RelativeLayout和LinearLayout的优点。(对于百分比布局,将会在以后的文章中有详述)
下面来说一下两个控件之间的基准约束条件。
将鼠标放置到Button A句柄处,当句柄开始变色(?)时用鼠标引导句柄,此时会从句柄处引申一条连接线,将此连接线连接到Button B 的句柄处,会发现Button A会移动到与Button B平齐(文字)的地方。(请注意右上角的警告数字,按照个人需求设置)。
在代码中的体现是在
下图是如何设置的动态图
好了,个人的设置大约就是这样,下面开始介绍Properties面板的若干参数的含义。
这个ImageView与上层布局的约束的状态。
想必各位看官们已经注意到了图中的16,50,39等数字,下面来给大家讲解一下各个数字的用处。16是当ImageView与上层布局出现约束关系时,四周与上层布局的间隔,也就是margin属性。用法一致,并没有发生改变。而50,39指的是50%和39%,相信大家看完下面的演示就会一目了然。
移动这个百分比比率会影响控件在布局中的位置(演示的有点小卡),这些百分比率就是在布局中的比率的显示。
在这张图中,还有一些代表意义。
1.在上图中有
,wrap_content,这个的含义,在新式布局中,
对应的是
对于wrap_content,在此就不做赘述,不知道或不明白的去面壁吧。
2.
,Fixed,对于这种样式,在布局中的代表含义是实际的距离,也就是我们给这个控件赋予的尺寸(指定的尺寸)。
3.
,AnySize,对于这种样式,让子控件占用尽可能大的所有可用空间以去适应上层布局.
看到在代码中的释义是不是很熟悉,又见0dp。
2. 自动创建约束
下面来看布局上面面板的内容,有经验的同学可以很快发现这个面板和以往的有所不同。
多了下面这一排的图标,这次我们会仔细讲解一下这些图标的作用。
现在我们将按照逻辑来讲一下各个图标。
1.
这个图标是左起第二个。作用是系统自动预测人类预期的行为而创建的约束—-简称自动创建约束(官方怎么称呼的我也不清楚)。
下面展示一下自动创建的流程。
开启磁铁符号,将控件放置在布局中,可以清晰的看到约束的关系在自动的创建。
在新式布局中还有一种自动创建约束的按钮,左起第四个,
,点击这个按钮系统会提示控件与控件,控件与布局之间的可能存在的约束关系。
详情见下面的动图:
这种自动约束的好处是免除自己去创建约束,但不好的地方在于约束太多,可能有很多约束不需要,而我们怎么删除这些约束呢?
下面我们来看第三个按钮,
,使用这个按钮就可以将所有的约束去除。如果不打算去除所有约束,而是不想将其显示出来,则使用第一个按钮,
,则可以将所有的约束关系显示/隐藏。(不贴图了,感兴趣的小伙伴们可以自己试试)
对于下面几个按钮,大家可以试试,是对控件进行操作。
比如:
是将控件的大小放置为可以容纳上层布局的最大的空间。
ConstraintLayout布局大约就是这些功能,现在看一下用这个布局做的一个简单的例子(丑,希望不要因为她丑而放弃他)。
在这里感谢!一叶飘舟 大神博客的帮助,带我走进ConstraintLayout布局的大门。感谢!