ConstraintLayout已经2.0了,你不来了解一下吗?

640?wx_fmt=jpeg


/   今日科技快讯   /


6月25日,中国移动在上海举办5G+发布会媒体沟通会,中国移动咪咕公司副总经理颜忠伟透露,即将开幕的MWC2019上海大会期间,国内首个8K超高清影院、首个5G超高清赛场等咪咕5G+超高清实践成果,都将在“全球5G沉浸式体验展”展示。


/   作者简介   /


本篇文章来自MarioFeng的投稿,和大家分享了ConstraintLayout 2.0的新特性,并进行了实战演练,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章。


MarioFeng的博客地址:

https://juejin.im/user/5919e8ef0ce46300690155a7


/   ConstraintLayout   /


ConstraintLayout在 1.0 的时候提供了GuideLine辅助布局,在 1.1 时提供了Group和Barrier,在 2.0 时候提供了Layer以及放开了限制,开发者可以自定义Helper了。


Group (Added in 1.1)


Group可以用来控制一组view的可见性


 
 


可以通过控制 group 的 hide/show 来直接控制一组 view(button4,button9) 的可见性。


Barrier (Added in 1.1)


来看一个场景,下面是一个表单,Email 和 Password 左对齐 中间的虚线为 GuideLine,具体字段都和GuideLine左对齐。


640?wx_fmt=jpeg


现在如果需要做多语言,翻译为德文后变成了下面的效果


640?wx_fmt=jpeg


这时候就需要Barrier出场了,Barrier是栅栏的意思,可以理解为挡着不让超过。


640?wx_fmt=jpeg


改进方法


  • 把中间的虚线GuideLine换成Barrier

  • 把①和②加入到Barrier的referenced_ids中

  • 指定barrierDirection为right(右侧不超过)

  • 把③和④左边对齐到Barrier的右边


这样 Email 和 Password就不会超出Barrier,大致代码如下(有删减,完整代码参考这里)

https://github.com/feng0403/ConstraintLayoutSamples/blob/master/app/src/main/res/layout/activity_main3.xml


 
 


Layer (Added in 2.0)


Layer 可以看作是它引用的 view 的边界(可以理解为包含这些 view 的一个 ViewGroup,但是Layer并不是ViewGroup,Layer并不会增加 view 的层级)。另外Layer支持对里面的 view 一起做变换。


考虑这么一个场景,如果一个页面里面有部分 view 需要加个背景,使用Layer引用这几个 view,然后给Layer设置背景就可以了。如果不用Layer,只能另外加个 ViewGroup 包住这几个 View 了,这样会增加 view 的层级,不利于性能。


看一个示例:


640?wx_fmt=gif


图中Layer包住了中间的 6 个按钮,绿色边线白色填充是通过 Layer设置背景完成的。另外对Layer里面的所有按钮一起做动画,出来的效果就是这样子。


ConstraintLayout2.0 除了提供几个默认实现的ConstraintHelper外,还提供开发者自定义ConstraintHelper的方式。


自定义 Helper


为什么需要自定义?


  • 保持 view 的层级不变,不像 ViewGroup 会增加 view 的层级

  • 封装一些特定的行为,方便复用

  • 一个 View 可以被多个 Helper引用,可以很方便组合出一些复杂的效果出来


如何自定义?


  • Helper持有 view 的引用,所以可以获取 view (getViews)然后操作 view

  • 提供了 onLayout 前后的 callback(updatePreLayout/updatePreLayout)

  • Helper 继承了 view,所以Helper本身也是 view


CircularRevealHelper


640?wx_fmt=gif


对一张图片作出CircularReveal的效果 ViewAnimationUtils给我们提供了createCircularReveal这个函数


 
 


借助这个函数只需要计算出中心点(centerX,centerY)和 endRadius(半径)就可以很方便实现CircularReveal的效果


 
 


updatePostLayout会在 onLayout 之后调用,在这里做动画就可以。


有了CircularRevealHelper之后可以直接在 xml 里面使用,在CircularRevealHelper的constraint_referenced_ids里面指定需要做动画 view。


 
 


后面如果要对 view 做CircularReveal直接在 xml 里面指定就可以了,做到了很好的复用。


FlyinHelper


640?wx_fmt=gif

再来看看这个 Flyin 的飞入效果,view 从四周飞入到各自的位置。

这个动画的关键在于计算出每个 view 该从什么方向飞入。

640?wx_fmt=png


红色边框的位置可以借助前面介绍的的Layer找到(当然也可以不借助Layer,自己算,稍显复杂),从而计算出红色框框部分的中间点位置, 再和图中每个 view 的中间点比较(图中每个白点的位置)从而得出每个 view 该从哪个方向飞入。


计算每个view 的初始位置代码如下,借助上面的图形应该很好理解。


 
 


FlyinHelper 的完整代码参考这里

https://github.com/ditclear/BindingListAdapter


ComposeMultipleHelper

每个 view 不但可以接受一个ConstraintHelper,还可以同时接受多个ConstraintHelper。

左边的四个ImageView和右下的FloatingActionButton都有Flyin的效果,同时左边的四个ImageView还在绕Y轴做3D旋转。上方的Seekbar的背景在做CircularReveal的效果。有了前面编写的CircularRevealHelper以及FlyInHelper 我们可以很方便做到这样的效果。


代码参考这里

https://github.com/feng0403/ConstraintLayoutSamples/blob/master/app/src/main/res/layout/layout_multiple_helper.xml


/   Flow   /


Flow是VirtualLayout,Flow可以像Chain那样帮助快速横向/纵向布局constraint_referenced_ids里面的元素。 通过flow_wrapMode可以指定具体的排列方式,有三种模式


  • wrap none :  简单地把constraint_referenced_ids里面的元素组成chain,即使空间不够


640?wx_fmt=png


  • wrap chain : 根据空间的大小和元素的大小组成一条或者多条 chain


640?wx_fmt=png


下面看下如何实现这个计算器布局:


640?wx_fmt=png


 
 


借助 flow 很快可以布局出来,这里flow_wrapMode使用的是aligned,id 为KE的TextView可以对齐到 Flow 里面的 view,id 为KR的TextView可以对齐到 Flow,另外 Flow 也是ConstraintHelper,所以Flow 也是个 View,可以设置背景,padding等元素。 那么这样布局有什么优势? 这样的布局 view 都在一个层级,不使用 ViewGroup,减少层级。


流式 APIs


1.1 之前需要这样修改属性


 
 


2.0 提供了ConstraintProperties 可以使用流式 API 修改属性



MotionLayout


关于MotionLayout可以参考ConstraintLayout开发者Nicolas Roard写的系列文章


Introduction to MotionLayout (part I)

https://medium.com/google-developers/introduction-to-motionlayout-part-i-29208674b10d


Introduction to MotionLayout (part II)

https://link.juejin.im/?target=https%3A%2F%2Fmedium.com%2Fgoogle-developers%2Fintroduction-to-motionlayout-part-ii-a31acc084f59


Introduction to MotionLayout (part III)

https://link.juejin.im/?target=https%3A%2F%2Fmedium.com%2Fgoogle-developers%2Fintroduction-to-motionlayout-part-iii-47cd64d51a5


Defining motion paths in MotionLayout

https://link.juejin.im/?target=https%3A%2F%2Fmedium.com%2Fgoogle-developers%2Fdefining-motion-paths-in-motionlayout-6095b874d37


/   写在最后   /


有任何问题或者疑问欢迎留言讨论,完整代码参考Github,喜欢的话star哦。


GitHub示例:

https://github.com/feng0403/ConstraintLayoutSamples


推荐阅读:

时隔两年,再度带你薅京东云的羊毛

使用黑科技启动未注册的Activity

原来这些设计模式的理念都是相同的


欢迎关注我的公众号

学习技术或投稿


640.png?


640?wx_fmt=jpeg

长按上图,识别图中二维码即可关注


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值