可以看到,第一个Group通过app:constraint_referenced_ids指定了a、c两个控件,这样当该Group可见性为invisible时,a、c的可见性都会变为invisible,为gone则都为gone。所以Group很适合处理有网无网之类的场景,不再需要像之前那样一个一个view控制可见性,通过Group就可以统一处理了。
Group有一些注意事项:
xml中,可见性配置的优先级:Group优先于View,下层Group优先于上层。
Group只可以引用当前ConstraintLayout下的View,子Layout 下的View不可以。
app:constraint_referenced_ids里直接写的是id的字符串,初始化后会通过getIdentifier来反射查找叫该名字的id。所以如果你的项目用了类似AndResGuard的混淆id名字的功能,切记不要混淆app:constraint_referenced_ids里的id,否则在release版本就会因找不到该id而失效。或者也可以通过代码setReferencedIds来设置id。
3. Placeholder
占位布局。他自己本身不会绘制任何内容,但他可以通过设置app:content="id",将id View的内容绘制到自己的位置上,而原id的 View就像gone了一样。
如下:
1 <?xml version="1.0" encoding="utf-8"?>
2
4
6 android:layout_width="50dp"
7 android:layout_height="50dp"
8 android:layout_marginLeft="30dp"
9 ...10 app:layout_constraintLeft_toLeftOf="parent"
11 app:layout_constraintTop_toTopOf="parent" />
12
13
15 android:layout_width="50dp"
16 android:layout_height="50dp"
17 android:layout_marginLeft="20dp"
18 ...19 app:layout_constraintLeft_toRightOf="@+id/a"
20 app:layout_constraintTop_toTopOf="@+id/a" />
21
22
24 android:layout_width="200dp"
25 android:layout_height="200dp"
26 app:content="@+id/a"
27 app:layout_constraintBottom_toBottomOf="parent"
28 app:layout_constraintLeft_toLeftOf="parent"/>
29
30
33 app:layout_constraintLeft_toRightOf="@+id/place" />
34
效果如图:
可以看到,原本B是位于A的右边并且顶部对齐的,但因为A被Placeholder引用,使A 相当于Gone了。而Placeholder的位置则显示了A的内容,并且大小也和A相符,Placeholder的大小设置并没有生效。
大概总结可以认为,Placeholder引用A后的效果是,原本位置的A gone,原本位置的Placeholder变为Placeholder的约束属性+A的内容属性。另外,Placeholder也支持使用代码setContentId动态的修改设置内容。
关于Placeholder的应用场景,网上其他人也都列出了一些例子:比如可以作为位置模板,引入后只需要写内容view;使用代码动态改变内容,结合TransitionManager可以做一些有趣的过度动画等。
4. Barrier
屏障,一个虚拟View。他主要解决下面遇到的问题:
如上图布局,两个TextView,一个button位于他们的右边。现在button设置的是在下面TextView的右边。假设有时候上面的TextView文本变长了,则布局会变为下面这个样子:
上面的TextView和Button重叠了。这时该怎么解决这个问题呢?Button只能设置一个View作为锚点,设置了上面就顾不了下面了。。。
所以就诞生了Barrier,他可以设置N个View作为锚点,使用方式如下:
1
3 android:layout_width="wrap_content"
4 android:layout_height="wrap_content"
5 app:barrierDirection="end"//end,left,right,top,bottom
6 app:constraint_referenced_ids="text1,text2" />
则Barrier始终位于text1,text2两个View最大宽度的右边,示意图如下:
这里基本的用法就讲完了。
下面再考虑一个情况,假如有如下的布局:
1 <?xml version="1.0" encoding="utf-8"?>
2
4
5
7 ...8 android:layout_marginTop="20dp"
9 />
10
11
13 ...14 android:layout_marginTop="40dp"
15 />
16
17
19 ...20 app:barrierDirection="top"
21 app:constraint_referenced_ids="a,b" />
22
23
25 ...26 app:layout_constraintTop_toTopOf="@+id/barrier" />
27
目前Button C和Button a、b的最上值对齐,没有问题。但如果a Gone了呢?效果如下:
其实也是符合逻辑,a gone后,会变为一个点,所以C顶齐父布局也没问题。但有的时候这不符合我们的需求,我们希望Barrier不要关注Gone的View了,所以谷歌提供了属性barrierAllowsGoneWidgets,设为false后,就不在关注Gone的View了,效果如下:
四、结束
本篇已基本上介绍完ConstraintLayout所有的属性了(除了代码写布局的ConstraintSet类)。相信ConstraintLayout之后会越来越强大。