Android ConstraintLayout详解

ConstraintLayout可能大家也比较熟悉了,在Google I/O 2016 上发布了 ConstraintLayout,也就是Android Studio 2.2中发布的新功能。以前我们写布局的时候基本都是靠编写XML,遇到复杂的布局避免不了多层嵌套,不可避免的会影响 UI 界面绘制的效率。目前对于复杂的界面,使用 RelativeLayout也无法解决,ConstraintLayout可谓RelativeLayout的升级版,但是要比前者强大太多。

Constraint翻译为约束,ConstraintLayout就是在子 View 上添加各种约束条件来控制每个子View所在的位置以及显示的尺寸。而且这一切都是通过可视化操作来实现的。当然,可视化操作的背后仍然还是使用的XML代码来实现的,只不过这些一切都是AS自动生成的

升级Android Studio2.3你会发现新建的XML根布局从以前的RelativeLayout变成了ConstraintLayout,可见Google对这个控件的重视,这也值得我们去学习。

ConstraintLayout 官方样例代码
ConstraintLayout Google官方文档

布局编辑器功能介绍
sssdsd.png

此界面是基于Android Studio 2.3的截图,相对与2.2很多图标做了改变,其中这几个主题区域是没变的

  1. Palette是控件区域,所有系统ViewLayout都在这里,可以分类查找。也可以直接搜索拖入布局中
  2. Component Tree当前布局的层级结构,当点击一个View的时候就会选中这个View
  3. 这里是对选中的View编辑操作的工具栏
  4. Design Editor 布局编辑器主窗口,可以通过点击左下DesignText切换编辑模式
  5. Properties可以修改当前选中View的各种属性。点击下面的图标可以查看更多的View属性

约束

约束帮助你保持控件对齐, 你可以使用锚点来确定各控件之间的对齐规则,要创建一个约束, 你需要在指定手柄上点击并按住鼠标, 然后拖到另一个控件的约束手柄. 一旦锚点变绿, 就可以松开鼠标完成约束创建。

GIF1.gif

这样就创建了一个简单的约束,BUTTON2位于BUTTON149dp的位置,这样BUTTON2的水平位置不会变,垂直位置就始终在BUTTON149dp处了不管BUTTON1如何移动。

GIF2.gif

现在我们想BUTTON2 水平和垂直位置都随着BUTTON1的位置改变而改变呢,我们需要添加新的约束,如下图

GIF3.gif

从图中我们可以看到BUTTON2的位置完全受BUTTON1的约束。

有很多常用的约束在顶部的工具栏中直接使用,用鼠标选中需要约束的控件然后在工具栏选择约束类型。

在增加一个BUTTON3,要让BUTTON2BUTTON3BUTTON1的右边对齐。

GIF4.gif

要让BUTTON2BUTTON3BUTTON1的顶部对齐

GIF5.gif

可以看到选择了约束模型后会自动创建好每一个View的约束,还有其他很多模型应该看图标就能看明白是怎么样的,我就不一一示范了(懒)。约束对象不仅可以是View也可以说是父布局。

GIF6.gif
基线约束

还有一种基线约束,其意为控件之间的文本基线约束。换句话说就是文本对齐,当然这种这种约束是有文本控件才有的约束,Layout是没有基线约束的。创建基线约束只需要选中控件然后点击左下角的第二个图标就会出现控件的基线,然后链接所需要对齐的其他控件就可以了

GIF8.gif
使用自动连接创建约束 Autoconnect

在工具栏有一个磁铁都一样图标


这个就是开启或关闭自动约束的开关,也叫Autoconnect 默认是开启的。Autoconnect会判断我们的意图,并自动给控件添加约束。不过Autoconnect是无法保证百分百准确判断出我们的意图的,如果自动添加的约束并不是你想要的话,还可以在任何时候进行手动修改。可以把它当成一个辅助工具,但不能完全靠它去添加控件的约,使用起来也很有局限性。 如下图所示

使用推理操作创建约束 Inference

Inference也是用于自动添加约束的,但它比Autoconnect的功能要更为强大,使用起来也很方便。因为AutoConnect只能给当前操作的控件自动添加约束,而Inference会给当前界面中的所有元素自动添加约束。可以一键自动生成所有控件的约束,如下图所示

删除约束

控件分别有四个方向上的约束点,四个角的正方形图标拖动可以改变控件的大小。要删除约束也很简单,选中控件后点击坐下角的图标就删除了当前控件的所以约束,点击某一个约束的原点可以删除单个约束

GIF7.gif

当然你也可以点击工具栏的上如下图的图标,那么会清除布局中所有的约束

Properties属性栏

当我们选中某个控件后那么视图的右边则是当前控件可以设置的属性栏。一些基本的属性设置这里就不讲解了,主要了解下如图所示的区域如何使用,这部分也叫Inspector 这部分就是来控制控件的宽高以及Margins值。

QQ截图20170324155606.png

相对约束定位控件

当一个控件上有至少两个对立的连接时, 比如上和下, 或者左和右, 你可以看到一个可以让你沿着对立连接的轴调整控件位置的滑块. 这也被称为横向或纵向偏量. 如下图

QQ截图20170324160027.png

拖动滑块可以改变控件的横向或者或者纵向的偏移量. 另外也可以通过移动控件到目标目标位置实现这一点。

控件宽高尺寸

空间的宽高可以通过单击下图中的线来控制控件宽高

4e632c6415c29e46.png

宽高有以下选项

  • Fixed: 此选项允许你指定控件的高和宽.
  • AnySize: 此选项让控件占用所有可用空间以适应约束. 换句话说, 这更像是匹配约束. 与 match_parent 不同, 后者占用父 View 的所有可用空间.
  • Wrap Content: 这个就是以前XML布局的Wrap Content是相同的

注意AnySizematch_parent 有所不同,如果 左边的ImageView 约束于右边的 Button, 设置为AnySize 只会扩展它适应 右边的button ,通过下面这张图应该就很好理解了。

点击外围的线可以调整控件的Margins值。

GIF10.gif

Guidelines

Guidelines可以帮助你在添加约束布局的时候更方便的确定控件的位置,可以创建垂直或者水平方向的Guidelines,创建后可以点击选择Guidelines位置的方式,默认是距离左边多少dp,点击后可以切位为距离右边的距离和屏幕的百分比距离

如果我们要两个按钮水平居中就需要用到Guidelines


可以看到我们给左边的按钮添加了约束,距离底部24dp 右边约束于Guidelines,右边的按钮则左边约束于Guidelines而顶部则于左边按钮对齐,这样两个按钮就水平居中对齐了。

链条布局 Chains

Chains 是最新才加入的一个新功能。 Chains 为同一个方向(水平或者垂直)上的多个子View 提供一个类似群组的概念。其他的方向则可以单独控制。Chain 的属性由该群组的第一个 View 上的属性所控制(第一个 View 被称之为 Chain head

首先我们创建一个水平方向的Chain,通过工具栏我们可以快速的创建一个Chain

可以看到我们快速的创建了一个Chain约束,Chain 的属性由该群组的第一个View也就是Chain head 上的属性所控制 。Chain head有很多属性如下

  • layout_constraintHorizontal_chainStyle
  • layout_constraintHorizontal_weight
  • layout_constraintVertical_chainStyle
  • layout_constraintVertical_weight

chainStyle 是设置到 Chain Head 上的,指定不同的 style 会改变里面所有 View 的布局方式,有如下四种 Style

  • CHAIN_SPREAD 这个是默认的 Style, 里面的所有 View 会分散开布局
  • Weighted chain,在 CHAIN_SPREAD 模式下,如果有些 View 的尺寸设置为 MATCH_CONSTRAINT(0dp),则这些View 尺寸会占据所有剩余可用的空间,和LinearLayout weight 类似。
  • CHAIN_SPREAD_INSIDECHAIN_SPREAD 类似,只不过两端的两个 View和 父容器直接不占用多余空间,多余空间在 子View 之间分散
  • CHAIN_PACKED这种模式下,所有的子View都 居中聚集在一起,但是可以设置bias 属性来控制聚集的位置。
chains-styles.png

如果多个子View尺寸设置为 MATCH_CONSTRAINT(0dp),则这些 View 会平均的占用多余的空间。通过layout_constraintHorizontal_weightlayout_constraintVertical_weight属性,可以控制每个View所占用的多余空间的比例。例如,对于只有两个 View的一个水平Chain,如果每个View 的宽度都设置为MATCH_CONSTRAINT, 第一个Viewweight为 2;第二个Viewweight 为 1,则第一个View所占用的空间是 第二个 View 的两倍。(以上其实就是官方文档翻译过来的)

比如我们现在想在界面上水平放置三个按钮,这三个按钮均分父容器宽度,且每个按钮的间距为8dp,首先我们就要设置Chain headchainStylespread并且layout_constraintHorizontal_weight设置为1

app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="1"

给剩余两个按钮添加

app:layout_constraintHorizontal_weight="1"

并且把按钮的宽度都设置为0dp然后修改margin

当我们修改最后一个按钮的layout_constraintHorizontal_weight为2的时候可以看到如下图

可以看到最后一个按钮的宽度是变成了前两个按钮的两倍,说明这个layout_constraintHorizontal_weightLinearLayoutweight类似

修改第一个按钮的layout_constraintHorizontal_chainStylepacked你会发现layout_constraintHorizontal_weight没有作用了,按钮宽度需要重新修改为wrap_content或者固定值。两边按钮的位置可以通过Bias调节,中间的按钮可以调节margin

最后需要注意的是每个控件都必须有上下左右的约束,这样才能确实控件在布局中的准确位置。在右上角的红色角标标识了当前有多少错误,错误一般都是控件没有某一个方向的约束,当然也可以在XML中查看错误信息

相信现在用ConstraintLayout去做一个复杂布局应该难不到你了,各种约束也可以满足各种样式的布局,Android Studio 2.3发布后ConstraintLayout已经成为了默认的根布局可以看出它的发展前途, ConstraintLayout简直是要变革 Android 写界面方式啊,更简便更高效!

THE END !

现在能用 ConstraintLayout 做些什么?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容