ConstraintLayout是Android Studio 2.2中主要的新增功能之一,也是Google在2016的I/O大会上重点宣传的一个功能。按字面意思来理解,就是约束布局,很多人也称它是RelativeLayout相对布局的进阶版,因为确实在布局方面与RelativeLayout类似,不过优化和强大了很多。在传统的android开发当中,界面基本都是靠编写XML代码完成的,虽然Android Studio也支持可视化的方式来编写界面,但是操作起来并不方便。而ConstraintLayout就是为了解决这一现状而出现的。它和传统编写界面的方式恰恰相反,ConstraintLayout非常适合使用可视化的方式来编写界面,但并不太适合使用XML的方式来进行编写。当然,可视化操作的背后仍然还是使用的XML代码来实现的,只不过这些代码是由Android Studio根据我们的操作自动生成的。
ConstraintLayout RelativeLayout
layout_constraintBaseline_toBaselineOf layout_alignBaseline
layout_constraintBottom_toBottomOf layout_alignBottom
layout_constraintBottom_toTopOf layout_above
layout_constraintEnd_toEndOf layout_alignEnd
layout_constraintEnd_toStartOf layout_toStartOf
layout_constraintLeft_toLeftOf layout_alignLeft
layout_constraintLeft_toRightOf layout_toRightOf
layout_constraintRight_toRightOf layout_alignRight
layout_constraintRight_toLeftOf layout_toLeftOf
layout_constraintStart_toStartOf layout_alignStart
layout_constraintStart_toEndOf layout_toStartOf
layout_constraintTop_toTopOf layout_alignTop
layout_constraintTop_toBottomOf layout_below
约束属性为ID时,两者总体上相差不大,但是用ConstraintLayout设置约束关系时直接在可视化下操作更加简洁方便。
而当约束对象为parent时。
Constraintlayout的约束必须上下或左右成对出现,而RelativeLayout则不需要。
如RelativeLayout子布局中
layout_alignParentTop="true"
会直接在子布局贴在父布局的顶部
而ConstraintLayout子布局中
layout_constraintTop_toTopOf="parent"
单这一条是没有用的,必须得成对出现,如下
layout_constraintBottom_toBottomOf="parent"
layout_constraintBottom_toBottomOf="parent"
其实添加了这一句也没办法让子布局贴在父布局的顶部,要实现这种效果,这就引出了Constraintlayout相对于Relativelayout的一个最大也有点那就是Constraintlayout可以比例控制布局位置与比例控制控件大小,这部分将在下文讲到。
也正因为此,ConstraintLayout兼顾了RelativeLayout与LinearLayout的优点,减少了复杂布局中多层嵌套的级数,优化渲染性能。
首先要在app/builder添加ConstraintLayout的依赖,不过在最新版的AS上,会自动添加
compile 'com.android.support.constraint:constraint-layout:1.0.2'
接下来讲解简单的用法
进入Design模式,拖一个Button进去,你会发现有两个视图,右侧是新加的蓝图模式,蓝图模式让view与view之间的依赖关系更加的清晰明了,还可以快速设置属性值.
在蓝图模式下点一下Button,可以看到该长方形的四条边出现了4个小圆圈(约束句柄)
我们添加或删除约束在界面操作下都是通过小圆圈来操作的,小圆圈其实为约束手柄,不过为了通俗易懂,后面我们都用小圆圈来代替。已添加的约束,再点一下相应的小圆圈即可删除该约束,拖动左边的小圆圈至左边界
来看看XML文件中自动生成的相应代码是什么
app:layout_constraintLeft_toLeftOf="parent
向上向左等也类似,这是与父布局对齐,来看看怎样和另外的view对齐。
现在再向布局中添加一个Button来实现相关的效果。
<1>.左对齐
将button2的左边的小圆圈接在button1的左边。就会有
没有对齐的重叠的原因是因为button2有默认的8dp的leftmargin,把它变为0
效果如图
<2>Button2紧贴在Button1下
在左对齐的情况下,讲Button2的上部圆圈与Button1的下部圆圈相连接,同样把默认的8dp的margin去掉。
来看看AS中自动生成的代码。
app:layout_constraintLeft_toLeftOf="@+id/button14"
android:layout_marginTop="0dp"
app:layout_constraintTop_toBottomOf="@+id/button14"
<3>实现重叠
将两个Button四边上的圆圈一一对应的相连,即可实现两个Button重叠的效果。
为了看出有两个Button,给第二个Button加了一个8dp的leftmargin,看看XML中自动生成的代码。
此约束是专门针对有TEXT的控件的,相应的控件直接实现文字对齐
点一下ab便会出现基线对齐选项
然后一样拖动使其与Text2的基线相连,便可实现文字底部对齐
来看看相应的XML代码
app:layout_constraintBaseline_toBaselineOf="@+id/textView4"
3.Properties 的Inspector部分
其实约束部分和RelativeLayout很相似,不过ConstraintLayout支持视图约束,下面来讲一下一些比较新颖的部分。
也就是这部分。把Button2的四个小圆圈与parent四个边界相连,就会有如下效果
就会垂直水平居中。当然有朋友会说我想靠左边或者靠右边一点怎么办。这就引出了我们ConstraintLayout相比于RelativeLayout最大的有点,比例布局,其中有控件位置比例属性与控件大小位置属性,我们先来说一下控件位置比例属性。
<1>控件位置比例属性
可能有细心的朋友已经发现的我们Inspector部分左边与右边有两个滚动条,这是干嘛用的?放在这里肯定是有作用的嘛。其实这就是控制控件在满足约束条件下调整的位置,竖着的滚动条是控制控件上下的调整,横着的是左右的调整。圆圈内的数值代表的是上部或者左部相对于整个可调整部分的控件所占的比值,这就是百分比定位。让我们看看水平垂直居中的代码。
app:layout_constraintVertical_bias="0.5"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.5" />
layout_constraintVertical_bias与layout_constraintHorizontal_bias其实就是与我们的两条滚动条相对应,其取值为0-1之间的数。
<2>控件大小
在探究控件大小比例之前,我们先来看看控件大小的三种模式。
不知道大家有没有注意到正方形区域内侧这四个图案呢,这就是控制控件大小模式调整的图案左右与上下是配套使用,通过点这个图案来切换模式。有三种模式,对应三种图案。
<1>
Fixed: 直译为固定的,即该模式下为固定尺寸,你可以通过操作正方形系下的width/height属性来控制控件的高和宽。
<2>
Anysize:该模式可以让控件占据所有可用的空间来满足约束。想match_parent但是有区别,Anysize的可作用范围是占据父视图的所有可用空间;AnySize模式下是满足约束的情况下尽量满足控件的大小空间。
下面简单对比一下,当就只有一个Button时,切换到Anysize模式,如图:
看起来貌似和match_parent没差,但是,当我在视图中再添加一个Button的时候就不一样了。
将原Button的右侧与新添加的Button左侧约束起来,再将Button1改成Anysize模式。如图
这就是所谓的在满足约束的情况下尽量满足控件大小。
提一下一个很方便的属性
constraintDimensionRatio属性,该属性是设置控件的宽高比的。
app:layout_constraintDimensionRatio="2:1",即设置控件的宽高比为2:1。
了解了控件大小,现在如果我要实现Button1的width占父布局的三分之一,Button2占三分之二,这要怎么实现?如果在RelativeLayout中,就得将两个Button加入到一个LinearLayout中再设置weight实现,但是这就是就增加的布局的嵌套级数,影响了性能。接下来,就让我们来看看ConstraintLayout中是如何实现的。
要实现控件大小按比例排放,得先认识一个工具,guideline。
Guideline:直译为引导线,顾名思义,就是起着引导作用的线,那这个线是怎么引导法呢?我们先来瞅瞅这是啥玩意儿。
这里就是guideline,我们添加一个垂直的guideline看看
就是个这么玩意儿。
它的作用是:其实质其实是给你个定位的基准,也就是引导,你可以将引导线作为一个约束对象,我们之前说AnySize模式下是满足约束的情况下尽量满足控件的大小空间。那么当你把垂直引导线置于页面宽度三分之一处,然后和Button1约束起来,这样子不就可以实现一个Button占三分之一,一个Button占三分之二了么。
下面来实践一下,首先点一下引导线最上方的小圆圈让它从dp刻度改为百分比刻度,之后将引导线置于视图宽度三分之一处然后添加约束。就有如下效果。
我们来看看Text中的XML代码:
最后来说一下自动链接,有些很简单的约束都需要手动岂不是很麻烦。谷歌提供了两种自动链接的方法。
<1>.Autoconnect
主要用于两个控件间自动添加约束,其会根据我们拖放的位置与所处的状态自动添加约束。
<2>Inference
主要用于多个控件间自动添加约束,其与Autoconnect的区别是Autoconnect是实时的,拖入一个控件时完成相应的约束,而inference是根据目前整体的布局来进行自动链接。
这个模块大家自己动手试试,相信很快就能弄明白了。
ConstraintLayout具有可视化设计布局十分友好的特性,同时能减少布局嵌套的层数,提高程序性能与渲染性能。基本上一些不含滚动的界面一层ConstraintLayout即可解决,即使在复杂的界面中,ConstraintLayout也具有十分优越的性能,兼顾了RelativeLayout与LinearLayout的优点,应用前景十分大,实现了从传统的XML文件中手写代码向可视化直接操作的转移。当然在复杂的界面设计中,Design与Text模式相结合更加提高程序的开发速度与简洁性。
PS:笔者也是刚踏入安卓这个大门的初学者,还在学习中,若有错误或不足之处欢迎指出并一起探讨。