ConstraintLayout属性之Group,GuideLine

Posted 安卓小小鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ConstraintLayout属性之Group,GuideLine相关的知识,希望对你有一定的参考价值。

在上期博客中[ConstraintLayout的居中显示以及常见问题剖析](https://blog.csdn.net/wzlyd1/article/details/83655680)
简单介绍了一下居中问题和字符串末尾显示…问题,其实就是写一下新属性在日常使用中的正确姿势。
上期还有两个问题没有解决,一个是
1.在某些逻辑下我要隐藏很多控件,为了方便,我在传统布局里可以将这些控件设置在一个ViewGroup里,就可以达到隐藏ViewGroup来简化单独的控件隐藏逻辑,现在新布局不让用布局嵌套了,我难道要一个个控件单独隐藏?
2.我所依赖的一个控件在某些逻辑下setVisibiltyGone后,自身的位置发生了重大偏差,怎么办?

为了解决第一个问题,我们需要引入一个新概念Group。如果你在XML中引用不到这些属性,请将build.gradle 中的implementation 'com.android.support.constraint:constraint-layout:1.1.3' 升级到最新,或者和我一样,是1.1.3

constraintLayout属性之Group

在传统的布局中,现实逻辑经常会隐藏某些控件,比如当价格不合理的时候回隐藏掉价格字段,或者没有简介的时候将其进行隐藏(只是随便举个例子)。
也就是当控件的数量很少的时候,我们只要通过id找到该控件将其Visibilty设置为Gone即可。
如果要是在某个逻辑下隐藏的View较多,我们通常会将其包裹在一个ViewGroup钟或者这些View已经在一个ViewGroup中,我们只需要隐藏Group即可达到隐藏全部控件的目的。
那么问题就来了,在constraintLayout中,控件与控件之间除了根View,没有其他父布局,怎么办?当然你也可以在外层嵌套一个ViewGroup,和传统布局一样,但是这样就背叛了constraintLayout设计的初衷。我也没这么做过,不知道会不会还有其他影响。
但是,不这么作我们难道要一个个去隐藏控件吗?这个真没必要,google爸爸为我么考虑好了,就是Group属性。简单用法如下图:

使用该app:constraint_referenced_ids="要包含的id名"属性即可实现隐藏所有控件的目的,这样就灵活多了,因为在传统布局中不是所有控件都适合放在同一个父布局中的。
然后在我们的java代码中,调用findViewById(R.id.group).setVisibility(View.GONE);即可。
但是如果你用了这个属性,将有一个比较大的问题就是,如果你又要将该组里的某个View做单独控制隐藏,调用了Gone之后,你会发现并没有生效。这是因为Group里的View显示属性已经被Group劫持。这一点在源码中可以找到原因

可是又有这种需求你该怎么办呢?
调用invisible属性,不要用gone,因为用gone属性会引起view的重新绘制与布局,在constraintLayout中会重新调用updatePreLayout函数,导致gone属性失效。
如果你还是喜欢用gone属性,另一个解决方案就是继承Group。重写updatePreLayout函数,因为这个函数很简单,所以不要担心会出问题,然后将要gone的ViewId从mIds这个函数中排除即可。(mIds这个数组是用来保存group中所有的id值。)具体可以看源码~

constraintLayout之GuideLine和marginXXX属性

上面的属性解决了一次性隐藏多个View的问题,但还有时候我们需要隐藏单个View,如果调用了Gone且不加注意,会导致UI出比较大的问题。
例如以下一段代码:

textView2 是以textView1为基准,所以当你把textView1设置为gone时候,textView2 的位置就飞了。
如图所示

所以日常在布局的过程中一定要注意gone这个属性,防止跑偏情况。但是在很多逻辑下,我们不得不使用gone属性,又不得不保持原有布局情况,那怎么办呢?
安卓爸爸给我们其实是提供了一些属性的:

	layout_goneMarginStart
    layout_goneMarginEnd
    layout_goneMarginLeft
    layout_goneMarginTop
    layout_goneMarginRight
    layout_goneMarginBottom

这些属性其实很简单,就是在某个子Viewgone的时候其他View如果不想受到其影响,可以设置该属性。比如B在A 的右面,A的宽度是100dp,同时B距A有10dp距离,那么当A为gone后,B要想保持不动,可设置layout_goneMarginLeft
为A的宽度+B距A的距离= 100dp+10dp =110dp;
当然了,我们最好的解决方案不是以一个可能会隐藏的view来做自己的基准View。
google为我们提供了一个更加轻量的基准View,GuideLine,我们可以叫他,辅助线。
与一般View不同的是,这个View只在布局的时候提供辅助,不会最终显示在手机上,而且很轻量。看源码便可知道。
具体用法如图所示

这样,我们就不用再每个View上设置marginxxx了。也会避免一些某个基准view呗设置为gone后导致布局错乱的问题。
基本属性就介绍到这里,接下来一篇将介绍百分比布局,因为constraintLayout给我们提供了丰富的百分比功能,利用这个功能,我们可以实现一些简单的适配工作,而不用再用java代码去重新计算宽高,下期见

以上是关于ConstraintLayout属性之Group,GuideLine的主要内容,如果未能解决你的问题,请参考以下文章

ConstraintLayout利用百分比属性来解决一些简单的适配问题

错题本:ConstraintLayout 不能正常显示

一分钟学会 ConstraintLayout 之从属性角度理解布局

Android开发 - 掌握ConstraintLayout分组(Group)

Android开发 - 掌握ConstraintLayout分组(Group)

ConstraintLayout约束布局使用全解