ConstraintLayout的使用小结+结合抽象布局优化

当小白的我一开始接触到ConstraintLayout(约束布局,以下简称为cons),我被这扁平化、减少嵌套的特殊布局吸引了。虽然我对其他布局了解不是太深入,但在很多博客、书籍里面都说过减少嵌套可以优化性能。在看了好几篇关于cons的实用技巧的博客,并且尝试学着文中布局之后,我成了cons的忠实拥趸。刚好想做一个复利计息的界面,按其他布局来计算应该会有至少三个层级的,我打算用cons下的一个层级就给搞定,然后真的做出来了 0.0 。实际上也修改了不少次,参考了不少博客,才做出来的。cons可能在上手时会有些难度,很多属性很抽象不好记忆,但对着下面我推荐的博客,假设一个嵌套层级较多的场景界面来练习几次,就会发现cons真的很好用。后面会有我觉得不错的博客,和我觉得我用的比较多的属性与小技巧。之后是我用cons一个层级完成的功能UI界面与代码(结合了抽象布局),可以参考一下,还有些我对cons使用的心得。


一、学习cons的博客推荐

首先推荐一下三篇关于cons的很棒的博客。

郭霖大神的简洁易懂的入门教程:Android新特性介绍,ConstraintLayout完全解析

接下来这俩篇就是进阶版了,因为是根据新版本来写的,所以用法更多样(俩篇侧重点不同,一起食用最好):

ConstraintLayout在项目中实践与总结

ConstraintLayout 用法全解析


二、cons常用属性和小技巧

从大佬们的博客里面学到了很多有趣的用法,这也是我想用cons的一方面原因。

约束布局的定位属性有十三种,我的记忆方式是 :

layout_constraint(本组件的部位)_to(建立连接的组件部位)Of:(建立连接的id)

  • 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

建议不用带left、right的属性,这样影响适配,横向只用start和end就好了。

cons中的每个属性建议至少使用俩个定位属性,这样大部分的界面都可以实现了。我的做法是一般都start和top位置的定位属性,这样对大多数左对齐的界面方便管理和编写代码。

另一个我觉得很实用的方法就是辅助线用法,我在看博客时学习了俩种辅助线的用法,一种是1px的view,用法如下:

 

 

 

ConstraintLayout的使用小结+结合抽象布局优化_第1张图片

 

 

 上方一整块背景是用一个view+颜色背景实现的,以为cons设置背景色只能在主布局中设置背景色,所以想实现如图的样式需要设置辅助线。view2本是

app:layout_constraintBottom_toBottomOf="@id/view"

但用android:layout_marginBottom="280dp",将它在原有的位置上上升了280dp,这个也刚好是view的高度,然后再把所有的组件一个个在view2下方放置就好了。

第二个辅助线就是官方的GuideLine,使用方法如下。



    

    

    

我在项目中定义了四条辅助线,可以看出其实 gl_top跟第一个方法用的view2是一样的作用,这个等一下说。

我觉得辅助线的精髓在于下面这俩条属性。

app:layout_constraintGuide_percent="0.5"

app:layout_constraintGuide_end="@dimen/margin_m"

这是给的辅助线的定位,既有百分比,又有具体距离的设置。百分比的设置让适配变得方便,具体距离的设置让组建的位置更为精准。有这个辅助线是实现稳定的组件们的线性排列变得方便。场景可参考项目图中的俩个edittext和俩个button的横向线性排列,用GuideLine后取代了线性布局的嵌套。

你们肯定要问了,设置view2这种抖机灵的小部件有何用,还消耗性能!不不不,我在刚才写博客时也想了一下,View2这种“自制辅助线”到底有何用呢。GuideLine只能在cons主布局中做组件的定位的辅助线,它的百分比和距离定位都是相对于主布局的,没法哪一个组件具体的辅助线,这是我们的“自制辅助线”就派上用场了,与某个组件建立约束,修改特定的margin值,就成了专属辅助线,在此辅助线建立的约束可以消去与其他组件的耦合(cons下的每个组件之间的关联太紧密,取消一个如牵一发而动全身,这也是很多人不想用cons的原因,但这个也是它的优势,精准定位,适配方便)。

解释一下,其实在我做的这个项目中,界面最上方的辅助线其实是不需要的(我也是写博客时才发觉),之所以没代码中没去掉是为了简单地演示一下辅助线的用法,cons中一个点(每个组件包括parent都有上下左右四个点)都可以建立多个约束的,所以组件覆盖另一个组件也是ok的(这好像是帧布局的功能0.0)。

此外cons很多实用方法,在我推荐的博客上可以看到。cons真的很强大!


三、参考项目

以下是我强迫症般地使用cons的界面截图,该项目的idea仅做参考(我知道不怎么好看。。。)

ConstraintLayout的使用小结+结合抽象布局优化_第2张图片

可以看出整个布局毫无嵌套,仅一个层级。真机界面看下图

ConstraintLayout的使用小结+结合抽象布局优化_第3张图片

当然,这个界面不算复杂,但只用一个层级就能做出来,那估计只有cons布局才能做到了。

你也许会说,这里有include,还有viewstub这种抽象布局,那里面肯定会有嵌套的啊。

客官莫急,且看代码。




    

    

    

    

    

    

    

    

以上是主要布局代码,看起来很少是因为蓝色部分组件给放进了calculator_merge里面了,而merge并不会增加层级,只是把代码分开,优化UI方便修改,都在一个xml里面看起来太臃肿了。merge支持主布局的规则,当然也支持主布局是cons。下面就是merge部分代码。



    

    

    

    

    

    

    

最重要的是下面一行代码,是我大佬回复我评论告诉我的。没有这段代码无法建立约束关系。

tools:parentTag="android.support.constraint.ConstraintLayout"

写在merge里面,唯一的不好就是太烦了,很多地方没有代码提示,可以现在主布局代码里面写好,再移过去。

说完了merge,再说说viewstub吧。先上代码



    

这是calculator_viewstub_btn.xml的代码。(好了,你不要再说了,我知道这是个滚动嵌套布局,,,,)然而这个嵌套却可以不需要initView时加载。viewstub可以算作一个占位符,它是是一个不可见的,大小为0的View,需要inflate()方法将它加载出来,然而只要在合适的时机加载,就不会影响UI初始化的性能了。我这个隐藏button的idea可以让ViewStub的使用场景变得更多。具体的实现我会在我的下一篇博客《ViewStub的奇淫巧技 》详细介绍。

四、对cons的使用心得与看法

通过我的介绍各位看官可以看出cons的强大,很多常用布局它都可以实现,当它跟抽象布局配合起来更强大。因为强大,它的源码也是多得惊人,虽然官方称ConstraintLayout在测量/布局阶段比RelativeLayout好40%左右,但是在onDraw()的阶段呢。所以深度嵌套肯定首选cons。cons的使用在刚上手的时候是比较繁琐,但建议你在使用多层嵌套布局时去试着多练习一下cons的使用,为了优化!

这个界面把三个抽象布局标签都用了,也算圆满了,希望这种布局优化可以给你提供一点思路。

写博客真得让我关注到了做项目时很多不注意的细节,感觉对cons的记忆更深刻了,这也许就是博客让人提升的地方吧。

望指正,谢谢!

参考:https://blog.csdn.net/stevenhenry/article/details/78954981

           https://blog.csdn.net/xyz_lmn/article/details/14524567

你可能感兴趣的:(Android布局)