ConstraintLayout2.x不仅包含 1.x 版本中的所有功能,还在 Android Studio(4.0+) 中集成了可以直接预览 XML 的工具,甚至可以直接在预览界面中对布局进行编辑。
Flow
Flow 是一种新的虚拟布局,它专门用来构建链式排版效果,当出现空间不足的情况时,它能够自动换行,甚至是自动延展到屏幕的另一区域。当需要对多个元素进行链式布局,但不确定在运行时布局空间的实际大小是多少,那么 Flow 就非常有用。你可以使用 Flow 来实现让布局随着应用屏幕尺寸的变化 (比如设备发生旋转后出现的屏幕宽度变化) 而动态地进行自适应。
下面动画展示了 Flow 创建多个链,将布局元素充裕地填充一整行:
Flow 是一种虚拟布局。在 ConstraintLayout 中,虚拟布局 (Virtual layouts) 作为 virtual view group 的角色参与约束和布局中,但是它们并不会作为视图添加到视图层级结构中,而是仅仅引用其它视图来辅助它们在布局系统中完成各自的布局功能。
在 ConstraintLayout 2.0 中,Flow 会通过传递的 constraint_referenced_ids 参数来获取到要引用的所有视图,然后根据这些视图创建一个虚拟的 virtual view group,再对这些视图进行链式布局。
例如实现一组控件水平展开放置,超出屏幕,自动换行展示,效果如下:
代码如下(由于Button没有设置约束条件,所以Android Studio 4.0 会报红,给ConstraintLayout布局添加tools:ignore=”MissingConstraints”忽略报红提示):
1 | <androidx.constraintlayout.widget.ConstraintLayout |
wrapMode
Flow 中最重要的一个配置选项是 wrapMode,它可以决定在内容溢出 (或出现换行) 时的布局行为。你可以对 wrapMode 指定三种模式:
- none – 这是flow默认模式,创建一个水平或者垂直链,所有引用的视图以一条链的方式进行布局,如果内容溢出则溢出内容不可见;
- chain – 当出现溢出时,溢出的内容会自动换行,以新的一条链的方式进行布局;
- align – 同 chain 类似,但是不以行而是以列的方式进行布局。
flow的wrapMode示意图:
View间隔
1 | flow_horizontalGap = “dimension” |
Flow布局的flow_horizontalGap属性表示水平之间两个View的水平间隔,flow_verticalGap则是垂直方向间隔。
链约束
flow_wrapMode属性为aligned和chian属性时,通过链进行约束。可以查看ConstraintLayout 详解中的链条(Chains)。
给Flow布局添加以下属性进行不同chain约束:
- flow_firstHorizontalStyle = “spread|spread_inside|packed” 约束第一条水平链,当有多条链(多行)时,只约束第一条链(第一行),其它链(其他行)不约束;
- flow_lastHorizontalStyle = “spread|spread_inside|packed” 约束最后一条水平链,当有多条链(多行)时,只约束最后一条链(最后一行),其它链(其他行)不约束;
- flow_horizontalStyle = “spread|spread_inside|packed” 约束所有水平链;
- flow_firstVerticalStyle = “spread|spread_inside|packed” 同水平约束;
- flow_lastVerticalStyle = “spread|spread_inside|packed” 同水平约束;
- flow_verticalStyle = “spread|spread_inside|packed” 约束所有垂直链;
以上属性的取值有:spread、spread_inside、packed,下方效果模式使用了 app:flow_wrapMode=”chain”的效果如下:
##对齐
上文XML布局中,所有TextView的宽高是一致的,所以看着整整齐齐,当宽高不一致时,可以进行对齐处理。经测试,app:flow_wrapMode=”aligned”下的对齐没有效果,下面是flow_wrapMode属性为none和chain情况。
给Flow布局添加以下属性进行不同Align约束:
- flow_verticalAlign 垂直方向对齐,取值有:top、bottom、center、baseline;
- flow_horizontalAlign 水平方向对齐,取值有:start、end、center;
对齐方向一般与链的方向相反才可生效,例如垂直链样式,一般对齐View的左右边和中间。
如下图是垂直方向顶部对齐。
可以看到E和G、F顶部对齐,代码如下:
1 | <androidx.constraintlayout.helper.widget.Flow |
##对View的组织方式
上文的XML的布局没有设置Flow对View的组织方式(水平or垂直),可以通过orientation属性来设置水平horizontal和垂直vertical方向,例如改为垂直方向。
##控制每行最大子View数量
当flow_wrapMode属性为aligned和chian时,通过flow_maxElementsWrap属性控制每行最大的子View数量。例如:flow_maxElementsWrap=3。
当flow_wrapMode属性为none时,A和G被挡住了,看不到。
偏移
- flow_horizontalBias = “float” 设置控件所有链的水平偏移,需要app:flow_horizontalStyle=”packed”才生效,取值为0-1;
- flow_verticalBias = “float” 与flow_horizontalBias同理,只不过是垂直的;
- flow_firstHorizontalBias = “float” 约束第一条水平链偏移,当有多条链(多行)时,只约束第一条链(第一行),其它链(其他行)不约束;
- low_lastHorizontalBias = “float” 约束最后一条水平链偏移,当有多条链(多行)时,只约束最后一条链(最后一行),其它链(其他行)不约束;
- flow_firstVerticalBias = “float” 同flow_firstHorizontalBias;
- flow_lastVerticalBias = “float” 同flow_lastHorizontalBias;
在上面的例子中,要A或者G可见,通过设置flow_horizontalBias属性,如下图所示:
设置flow_horizontalBias=1那么G就可以看到了。
代码如下:
1 | <androidx.constraintlayout.helper.widget.Flow |
Layer
Layer 作为一种新的辅助工具,可以让你在多个视图上创建一个虚拟的图层 (layer)。同 Flow 不同,它并不会对视图进行布局,但可对该图层进行背景色、可见性、elevation、padding、transformation等一些操作。
如果想对多个视图整体进行旋转 (rotate)、平移 (translate) 或缩放 (scale) 操作,那么 Layer 将会是最佳的选择。
图层 (layer) 在布局期间会调整大小,其大小会根据其引用的所有视图进行调整。
下面给ImageView和TextView添加一个共同背景,Layer是约束助手ConstraintHelper的子类,由于ConstraintHelper本身继承自View,跟我们自己通过View在ConstraintLayout布局中给多个View添加共同背景没什么区别,只是更方便而已:
代码如下:
1 | <androidx.constraintlayout.widget.ConstraintLayout |
效果如下:
通过属性动画给ImageView和TextView添加通过动画效果,代码如下:
1 | final ValueAnimator animator = ValueAnimator.ofFloat(0f, 360f); |
效果如下:
自定义ConstraintHelper
Flow和Layer都是ConstraintHelper的子类,当两者不满足需求时,可以通过继承ConstraintHelper来实现想要的约束效果。比如如下效果:
通过自定义ConstraintHelper来实现就非常简单,代码如下:
1 | public class ADHelper extends ConstraintHelper { |
布局引用AdHleper:
1 | <androidx.constraintlayout.widget.ConstraintLayout |
ImageFilterButton与ImageFilterView
两个控件基本相同,只是它们继承的父类不一样,一些操作也就不一样。ImageFilterButton继承自AppCompatImageButton,也就是ImageButtion。而ImageFilterView继承自ImageView,同ImageView与ImageButton之间的关系。
圆角
- roundPercent=”float” 设置图片圆角率(0-1),如果图片是一个正方形,此时roundPercent设置为1,则是显示一个圆。
代码如下:
1 | <androidx.constraintlayout.utils.widget.ImageFilterView |
如下分别是roundPercent为1和0.5的方形图以及roundPercent为1的长形图效果:
- round=”dimension” 设置图片圆角大小
类似如下代码:
1 | <androidx.constraintlayout.utils.widget.ImageFilterButton |
图片资源
- altSrc=”reference” 通过altSrc设置的资源,允许交叉淡入淡出
- crossfade=”float” 改变使用altSrc设置的资源透明度(0-1),使得底层图片的显示程度
- overlay=”boolean” 设置altSrc设置的资源图像是在原始图像上淡入淡出还是与它交叉淡入淡出。默认为true。
altSrc和src属性是一样的概念,altSrc提供的资源将会和src提供的资源通过crossfade属性形成交叉淡化效果。默认情况下,crossfade=0,altSrc所引用的资源不可见,取值在0-1。 例如:
代码如下:
1 | <androidx.constraintlayout.utils.widget.ImageFilterView |
效果如下:
对图片进行调节
- warmth=”float” 设置图片表现色温。1=neutral自然,2=warm暖色,0.5=cold冷色。
- saturation=”float” 设置图片的饱和度。0 =灰度,1 =原始,2 =超饱和
- brightness=”float” 设置图片的亮度 0 =黑色,1 =原始,2 =两倍的亮度
- contrast=”float” 设置图片对比度。0 =灰色,1 =不变,2 =高对比度
各个效果如下:
上面属性的取值都是0、1、2,也可以取其它值,效果是不一样的。
MockView
MockView可用于对布局进行原型制作,可以绘制标签(默认为视图ID)以及对角线的基本视图,在构建UI时可用作临时模拟视图。
代码如下:
1 | <androidx.constraintlayout.widget.ConstraintLayout |
效果如下:
一些参数解释:
- mock_label=”string” 设置中间label文字,默认为控件id
- mock_labelColor=”color” 设置label文字颜色
- mock_labelBackgroundColor=”color” 设置label背景颜色
- mock_diagonalsColor=”color” 设置辅助线颜色
- mock_showDiagonals=”boolean” 设置是否显示辅助线
- mock_showLabel=”boolean” 设置是否显示label
显示如下:
MotionLayout
详见ConstraintLayout2.x之MotionLayout
参考资料:
谷歌开发者 Constraint Layout 2.0 用法详解
新小梦 Constraintlayout 2.0:你们要的更新来了
zping0808 ConstraintLayout2.x使用详解