专栏首页Android先生细细品读!深入浅出,官方文档看ConstraintLayout

细细品读!深入浅出,官方文档看ConstraintLayout

作者:代码咖啡

地址:http://www.jianshu.com/38ee0aa654a8

声明:本文是代码咖啡原创,已获其授权发布,未经原作者允许请勿转载

写在前面

之前品读了郭霖大神写的《Android新特性介绍,ConstraintLayout完全解析》,受其感染,写了一篇《未来布局之星——ConstraintLayout》,回过头来看,感觉这一篇文章太注重可视化操作,于是去翻阅了一下ConstraintLayout的官方文档,决定从官方文档的角度在代码层面来了解一下ConstraintLayout。

继承关系

继承关系

ConstraintLayout和其他布局一样,继承自ViewGroup,但是不同点在于它调整控件的位置和大小时更加得灵活,功能更加强大。

版本支持

ConstraintLayout是一个Support库,意味着向前兼容,它可以兼容至API 9,也就是Android 2.3,鉴于现在市场上手机基本都是2.3及以上的,所以如果不是特殊情况,开发者可以不用考虑版本问题。下面是官网文档引文:

新特性

相对于传统布局,ConstraintLayout在以下方面提供了一些新的特性:

  • 相对定位
  • 外边距
  • 居中和倾向
  • 可见性的表现
  • 尺寸约束
  • Chain
  • 辅助工具

接下来就这些新特性进行详细了解。

相对定位

相对定位是在ConstraintLayout中创建布局的最基本构建块,也就是一个控件相对于另一个控件进行定位,可以从横向、纵向添加约束关系,用到的边分别有:

  • 横向:Left、Right、Start、End
  • 纵向:Top、Bottom、Baseline(文本底部的基准线) 通常是一条边另一条边添加约束,就像下面按钮B要定位在按钮A的右边一样:

这种情况代码实现是这样的:

这样系统就会知道按钮B的左侧被约束在按钮A的右侧,这里的约束可以理解为边的对齐。

上图是相对定位的约束,图中每一条边(top、bottom、baseline、left、start、right、end)都可以与其他控件形成约束,罗列这些边形成的相对定位关系如下:

上面的这些属性需要结合id才能进行约束,这些id可以指向控件也可以指向父容器(也就是ConstraintLayout),比如:

外边距

这里的外边距相信大家都理解,这里就不赘述了,罗列外边距的属性如下:

来主要看一下外边距的新属性:GONE MARGIN 以图 3为例,这里的gone margin指的是B向A添加约束后,如果A的可见性变为GONE,这时候B的外边距可以改变,也就是B的外边距根据A的可见性分为两种状态。

居中和倾向

居中

相对定位一小节,我们了解了两个控件之间添加约束,现在来看看一个控件和父布局(ConstraintLayout)建立约束。当相同方向上(横向或纵向),控件两边同时向ConstraintLayout添加约束,情况就会像图 4所示的这样。

而代码的书写是这样的:

这种情况就感觉像是控件两边有两个反向相等大小的力在拉动它一样,所以才会产生控件居中的效果。

这里说明一下:如果在居中方向上(横向或纵向)控件的尺寸和ConstraintLayout的尺寸一样,那么就无所谓居中了,此时约束的存在是没有意义的。

倾向

在这种约束是同向相反的情况下,默认控件是居中的,但是也可以像拔河一样,让两个约束的力大小不等,这样就产生了倾向,其属性是:

下面这段代码就是让左边占30%,右边占70%(默认两边各占50%),这样左边就会短一些,如图5所示,此时代码是这样的:

通过设置倾向,可以非常便捷地实现屏幕适配。

可见性的表现

ConstraintLayout对可见性被标记View.GONE的控件(后称“GONE控件”)有特殊的处理。一般情况下,GONG控件是不可见的,且不再是布局的一部分,但是在布局计算上,ConstraintLayout与传统布局有一个很重要的区别:

  • 传统布局下,GONE控件的尺寸会被认为是0(当做来处理)
  • 在ConstraintLayout中,GONE控件尺寸仍然按其可见时的大小计算,但是其外边距大小按0计算

这种特殊的行为让我们在无需打乱布局情况下,在标记GONE控件的地方构建布局,这样的做法对于做简单的布局动画很有用。

说明一下

笔者在理解原文这句话的时候不是很理解,希望有经验的读者可以指点迷津,原文如下:

关于目标控件(如图 6中的A)设置为GONE时,受约束的控件(如图 6中的B)的外边距的变化设置请查看上面的外边距小节的GONE MARGIN属性。

尺寸约束

ConstraintLayout中的最小尺寸

ConstraintLayout本身可以定义自己的最小尺寸:

  • android:minWidth 设置布局的最小宽度
  • android:minHeight 设置布局的最小高度

这些最小尺寸当ConstraintLayout被设置为WRAP_CONTENT时有效。

控件尺寸约束

控件的尺寸可以通过android:layout_widthandroid:layout_height来设置,有三种方式:

  • 使用固定值
  • 使用WRAP_CONTENT
  • 使用0dp(相当于MATCH_CONSTRAINT

前两种方式和其他布局的用法相同,最后一种是通过填充约束来重新设置控件的尺寸(如图 7,(a)是wrap_content,(b)是0dp)。代码案例如下:

如果控件设置了外边距,那么外边距就会在尺寸计算中被考虑进去,效果如图图 7 (c)所示。

敲黑板,划重点

一般MATCH_PARENT在ConstraintLayout布局下是不支持的,但是在简单的布局结构(如控件的约束只与ConstraintLayout关联)下,MATCH_PARENT是被支持的,其作用与MATCH_CONSTRAINT相同。

比例

这里的比例指的是宽高比,通过设置比例,让宽高的其中一个随另一个变化。为了实现比例,需要让控件宽或高受约束,且尺寸设置为0dp(也可以是MATCH_CONSTRAINT),实现代码如下:

上述代码中,按钮的高度满足受约束且设置为0dp的条件,所以其尺寸会按照比例宽度调整。

比例的设置有两种格式:

  • 宽度与高度的,可理解为受约束的一方尺寸:另一方尺寸
  • 受约束的一方尺寸/另一方尺寸得到的浮点数

如果宽高都设置了MATCH_CONSTRAINT0dp)和约束,那么需要在比例前添加W,H,以确定受约束的是高还是宽,然后受约束的一方根据不受约束的一方,按照比例计算自己的尺寸。

关于上面这段话,原文是:

笔者个人感觉官方文档对于这一块表述较模糊,可能跟自己的英语阅读能力有关,望有经验的过来人答疑解惑。

关于上述的案例,代码如下:

上述代码对宽度和高度都进行了约束,通过H,指定高度受约束,所以高度的尺寸会根据宽度大小按照比例得到,其效果如图所示:

至于为何高度填充屏幕而宽度不填充,其玄机在于下面这句话,能理解它,就理解了比例使用的精髓:

Chain

Chain是一系列双向连接的控件连接在一起的形态(如图 8所示,是最小单位的Chain,只有两个组件)。

Chain头部

横向上,Chain头部是Chain最左边的控件;纵向上,Chain头部是Chain最顶部的控件。

Chain外边距

如果连接时定义了外边距,Chain就会发生变化。在SPREAD CHAIN中,外边距会从已经分配好的空间中去掉。原文如下:

Chain样式

当对Chain的第一个元素设置layout_constraintHorizontal_chainStylelayout_constraintVertical_chainStyle属性,Chain就会根据特定的样式(默认样式为CHAIN_SPREAD)进行相应变化,样式类型如下:

  • CHAIN_SPREAD 元素被分散开(默认样式)
  • CHAIN_SPREAD模式下,如果一些控件被设置为MATCH_CONSTRAINT,那么控件将会把所有剩余的空间均分后“吃掉”
  • CHAIN_SPREAD_INSIDE Chain两边的元素贴着父容器,其他元素在剩余的空间中采用CHAIN_SPREAD模式
  • CHAIN_PACKED Chain中的所有控件合并在一起后在剩余的空间中居中

带权重的Chain

默认的Chain会在空间里平均散开。如果其中有一个或多个元素使用了MATCH_CONSTRAINT属性,那么他们会将剩余的空间平均填满。属性layout_constraintHorizontal_heightlayout_constraintVertical_weight控制使用MATCH_CONSTRAINT的元素如何均分空间。

例如,一个Chain中包含两个使用MATCH_CONSTRAINT的元素,第一个元素使用的权重为2,第二个元素使用的权重为1,那么被第一个元素占用的空间是第二个元素的2倍。

辅助工具

这里“辅助工具”的原文是Virtual Helper objects,对于ConstraintLayout,其辅助工具目前是Guidline。关于Guideline的了解,读者们可先尝试《未来布局之星——ConstraintLayout》一文中的Guideline操作。在此基础上,访问Guideline类了解详情,附上Guideline类的代码案例供读者们了解:

相关方法

写在最后

第一次用所剩无几的英语能力蹩脚地翻译官方文档,看着密密麻麻的英文写到这里,如今已经头昏眼花、不知所云,若读者们有发现文章错误的地方,欢迎在文章下方评论留言。个人感觉,想要深入理解ConstraintLayout,还是需要多使用、多实践,并且要结合源码分析,但愿通过这篇文章的学习,读者们可以达到入门ConstraintLayout的目的。翻译不易,转载请注明链接,最后附上官方文档的地址,供读者们比对学习,感谢阅读! https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout.html

本文分享自微信公众号 - Android先生(cyg_24kshign),作者:代码咖啡

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-09-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你知道有几种方式来判断JS的数据类型吗?

    因为JavaScript是一门弱引用类型的语言,所以在开发过程中我们常常会遇到 “我定义的这个变量是什么数据类型?”这种类似的问题,所以今天我们来看看在JS中一...

    用户2802329
  • Android-Annotation教你写自定义注解

    地址:https://juejin.im/post/5a14158df265da432c237bfc

    用户2802329
  • 写给小白的android基础面试笔试题(一)

    序言:由于公司的某些方面原因,LZ最近都处于找工作的状态,年关了,最关键的LZ还只是个没毕业的孩子,所以工作越来越不好找了,到哪里投简历都是动不动就好几年经验,...

    用户2802329
  • Java远程调试(Remote Debugging)的那些事

    这篇文章将研究如何处理和调试那些只发生在生产环境(或其他远程环境)而本地开发环境可能没办法重现的“问题”。任何碰到过这种情况的人都不得不承认,试图定位这种“问题...

    曲水流觞
  • KPMG:2019年上半年全球金融科技投资报告(美国篇)

    添加微信: a19921690890或ddkjzx1,备注要加入的专业群,通过后请发名片,实名审核后邀请进群!

    点滴科技资讯
  • # 如何调试go源码

    用户1175783
  • 微软VMware高层口水仗:虚拟化谁最强?

    很明显,微软想要“吃掉VMware的午餐”。这至少是微软COO Kevin Turner在最近于华盛顿召开的便于合作伙伴大会上公开给出的结论。 他显然已经作好了...

    静一
  • 计算机网络面试复习

    UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效...

    黑白格
  • 2019秋招:460道Java后端面试高频题答案版【模块五:计算机网络】

    计算机网络、计算机操作系统这两个“兄弟”是所有开发岗位都需要“结拜”的,不管你是 Java、C++还是测试。对于后端开发的童鞋来说,计算机网络的重要性不亚于语言...

    乔戈里
  • 横扫13项中文NLP记录,中文字型深度学习模型Glyce问世!

    [ 导读 ]香侬科技近期提出 Glyce,首次在深度学习的框架下使用中文字形信息(Glyph),横扫 13 项中文自然语言任务记录,其中包括:(1) 字级别语言...

    数据派THU

扫码关注云+社区

领取腾讯云代金券