ConstraintLayout最强布局解析

ConstraintLayout布局出来已经很久了,刚出来那会儿就想尝试一下的,结果半天都没适应,前两天看到一篇ConstraintLayout实战的文章,看完之后发现这布局贼鸡儿好用啊,日常开发中的大多数布局使用它都可以完成,而且也不需要嵌套。

介绍

ConstraintLayout又称约束布局,是谷歌在2016年开发者大会上推出的,之后在Android Studio上成为了默认布局,该布局能减少布局的层级嵌套,我们都知道,View嵌套的越多,在加载的过程中解析起来就越费时间,该布局几乎能做到LinearLayoutRelativeLayout嵌套完成的任何布局,下面跟着一波小demo来深入了解谷歌推荐的ConstraintLayout

用法简介

1、xxx_toyyyOf属性

xxx是当前的控件,yyy是指定控件,这个指定控件也可以是容器本身(parent)

ConstraintLayout中有以下多种这样的属性:

  • layout_constraintLeft_toLeftOf

  • layout_constraintLeft_toRightOf

  • layout_constraintRight_toLeftOf

  • layout_constraintRight_toRightOf

  • layout_constraintTop_toTopOf

  • layout_constraintTop_toBottomOf

  • layout_constraintBottom_toTopOf

  • layout_constraintBottom_toBottomOf

  • layout_constraintBaseline_toBaselineOf

  • layout_constraintStart_toEndOf

  • layout_constraintStart_toStartOf

  • layout_constraintEnd_toStartOf

  • layout_constraintEnd_toEndOf

image

参照上图给出的解释,以上属性都可以这样用,有点类似RelativeLayout中的toLeftOftoRightOf,上面的属性中还有一个关于Baseline的,我们通过另外一张图来了解一下:

image

Baseline是控件中文字的基准线,这里可以理解为参照某个控件中的文字底部对齐,来看看样式:

image

如果不加基准线对齐的话,那么ButtonA的位置就在容器的左上角。

2、设置margin边距

边距,和传统的布局是一样的用法,但是这里要注意的是,必须要设置自己的相对位置(先要指定自己在容器中的位置,可以是相对容器的,也可以是相对某个控件的),如果不设置的话,那么设置margin是无效的,大家可以试试,在一个ConstraintLayout布局中放一个按钮,除了边距之外什么都不设置,这样是没有效果的,因为你没有在布局中给它设置相对位置。

3、隐藏空间设置边距

ConstraintLayout中有以下多种这样的属性:

  • layout_goneMarginStart

  • layout_goneMarginEnd

  • layout_goneMarginLeft

  • layout_goneMarginTop

  • layout_goneMarginRight

  • layout_goneMarginBottom

平常我们在开发过程中会遇到这样一个问题,当一个控件被设置成gone之后,与之关联的控件的位置常常也会发生改变,来看看样式:

image

平常我们写标题栏的时候应该都遇到过右边放两个按钮的情况,而且是可以控制显示隐藏的,当最右边的按钮隐藏之后,左边的按钮也要距离右边有一个边距,这种情况下我们就可以使用上面这些属性来配置布局。

4、居中和偏移

  • 水平居中
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
image

这个很好理解,设置与容器的左边和右边分别对齐,这样的话就能让控件水平居中了,同理垂直居中和中心对齐也是这样。可能有人会吐槽了,写这么多还不如我用LinearLayoutRelativeLayout写一句代码来的快呢?老铁还真是个急性子,接着往下看。

  • 垂直居中
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
  • 中心
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

下面来实现一个这样的功能,让一个控件在距离左边和距离右边的比例是1:3,来看看正经写法:

image
<LinearLayout>

    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
        
    <Button
        android:layout_width="100dp"
        android:layout_height="match_parent" />
    
    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />

</LinearLayout>

相信大多数老铁都会这么写,那么我们现在来看看不正经的写法:

<android.support.constraint.ConstraintLayout>

    <Button 
        android:id="@+id/button"
        app:layout_constraintHorizontal_bias="0.33"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent />
        
</android.support.constraint.ConstraintLayout>

看到这个是不是惊呆了,一行代码就搞定了,简直不要太简洁。

5、CircleRadius角度定位(在版本1.1中加入)

image

官网给出的解释是,你可以以角度和距离约束窗口小部件中心相对于另一个窗口小部件中心。可能有些人看不太懂,我也没看懂(哈哈,LZ你是来搞笑的吗),但是看官网给出的图我大概明白是什么意思了,简单来说就是可以根据两个控件的中心来形成约束关系,然后可以通过设置角度来控制这个约束关系(还看不懂的话那就来实践一把)

image

layout_constraintCircle表示相对某一指定控件,上图中表示相对ButtonAlayout_constraintCircleRadius表示该控件的中心点到指定控件的中心点的距离(两点之间,直线最短);layout_constraintCircleAngle表示该控件的中心点在指定控件垂直方向上的角度(范围是0-360),具体看上图中标示的。

6、尺寸约束

ConstraintLayout布局中,你可以设置布局的最大和最小尺寸,而且你可通过三种方式来设置控件的大小:

  • 特定数值,比如123dp

  • 使用wrap_content,控件将自己计算大小

  • 使用0dp,相当于MATCH_CONSTRAINT

注意:match_parent官方不建议在ConstraintLayout布局中使用,可以通过设置MATCH_CONSTRAINT(真实数值是0dp)配合约束来定义布局

下面我们来看一个例子:

image

ButtonA是固定宽度且靠左,给ButtonB设置了约束,刚开始预期的是设置ButtonB的宽度慢慢增大,超过ButtonA之后不管设置多大都像ButtonCButtonD一样,但是ButtonA却把ButtonB覆盖了,显然这不是我们需要的,这时候MATCH_CONSTRAINT的作用就能体现出来了,怎么理解这个MATCH_CONSTRAINT,我们可以理解成为了配合约束布局而代替了match_parent

7、设置宽高比例

在使用百分比布局时,有两种形式可以设置:

  • layout_constraintDimensionRatio,给宽或者高其中一个设置为0dp,然后设置该属性是一个比例,宽和高的比(相对那个已知长度的),可能说的有点绕,下面我们直接看demo:
image
  • app:layout_constraintDimensionRatio,设置宽和高都为0dp,然后设置改属性的值为H,x:y 或者 W,x:y,看一下demo
image

8、Chains(链)

链条在同一方向上(水平或者垂直)为一组互相关联的控件作统一管理,并且链由链头(链的第一个元素)设置的属性控制,链头是水平链的最左侧的元素,是垂直链的最顶部的元素。我们来看看一些链的样式:

image

我们只需要设置layout_constraintHorizontal_chainStyle或者layout_constraintVertical_chainStyle的属性就好了,而这个属性有以下几种配置:

  • CHAIN_SPREAD模式:元素将展开(默认样式)

  • 加权链CHAIN_SPREAD模式:如果给元素的宽或者高设置了MATCH_CONSTRAINT(0dp),它们将分割宽高方向上的可用空间

  • CHAIN_SPREAD_INSIDE模式:类似于SPREAD,但链的端点不会分散

  • CHAIN_PACKED模式:链条的元素将被捆绑在一起。然后,子项的水平或垂直偏差属性将影响该链元素的定位

9、辅助布局Guildline

这是ConstraintLayout布局特有的功能,你可以用它来辅助你完成布局,类似于高中数学图形学中的辅助线,只不过这条辅助线只有两个方向,水平和垂直:

  • 当设置线的方向为horizontal时,辅助线的高度为0,宽度是容器的宽度。

  • 当设置线的方向为vertical时,辅助线的宽度为0,高度时容器的高度。

我们来看看Guildline的样式(需要注意的是,辅助线是不可见的,只有在预览的时候才能通过鼠标选中可见):

image

Guildline有三个常用的属性,用来控制辅助线的位置:

  • layout_constraintGuide_begin:指定辅助线距离左边或者顶部的距离

  • layout_constraintGuide_end:指定辅助线距离右边或者底部的距离

  • layout_constraintGuide_percent:指定在父控件中的宽度或高度的百分比

代码

以上demo的代码全都上传至ConstraintLayout最强布局解析,有兴趣的童鞋可以自行下载看看

参考

官网ConstraintLayout讲解

泓洋_ConstraintLayout 完全解析

实战篇ConstraintLayout的崛起之路

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

推荐阅读更多精彩内容