参考
Android新特性介绍,ConstraintLayout完全解析
史上最全ConstraintLayout使用详解
概述:
约束布局,各个控件可以依据某些约束法则排列
位置功能:
相对位置
相对父控件位置
layout_constraintBottom_toBottomOf 这样的结构,可以记忆为
layout_constraintBottom 本控件位置指示 底部
toBottomOf 相对的控制位置指示 底部
app:layout_constraintBottom_toBottomOf="parent" 代表 本控件的底部位置和parent父控件的底部位置一致
一般而已,我们有Bottom,Top,Start,End 几个类型,其中Start,End和Left,Right是一致的,只是因为有些国家的left和right不是一致的,所以统一用Start,End代表。虽然Start,End和Left,Right是一致的,但是要注意Start,End是一对,Left,Right是一对,不可以混搭使用。
app:layout_constraintBottom_toBottomOf="parent" //本控件的底部位置和parent父控件的底部位置一致
app:layout_constraintEnd_toEndOf="parent"//本控件的结束位置和parent父控件的结束位置一致
app:layout_constraintStart_toStartOf="parent"//本控件的开始位置和parent父控件的开始位置一致
app:layout_constraintTop_toTopOf="parent"//本控件的头部位置和parent父控件的头部位置一致
下面代码,就是TextView的位置相对于父控件位置上下左右都是一致,因为四周都约束了,结果就是再中间
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<TextView
android:id="@+id/imageView"
android:text="TextView 1"
android:background="@color/colorAccent"
android:layout_width="200dp"
android:layout_height="200dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
如果控件没有约束四边,就会有不同的效果,如下图,只约束了两边,控件的下方和父控件一致,控件的右边和父控件一致,就会导致控制整个变成右下
相对某个控件位置
和相对于父控件位置很相似,核心代码都是layout_constraintBottom_toBottomOf
,只是后面变成="
@+id/viewId"
如下图,就是TextView2底部和TextView1的头部对齐,开始位置和结束位置和父控件对其
偏移量
当给控件增加了Top和Bottom的约束,就可以竖向产生偏移量,如果是增加了Start和End约束,就可以横向的偏移量。在可视化的属性里面,就是这里的滑动按钮
如果是在代码里面,就是layout_constraintVertical_bias和layout_constraintHorizontal_bias,后面参数是百分比
控件大小
在ConstraintLayout里面,控件大小总共有三种方式
Fixed 固定大小
layout_width和layout_height 里面填写固定的大小就可以,在可视化的属性里面(Attributes)看到的样子就是这样
包裹大小 wrap_content
layout_width和layout_height 里面都是wrap_content,就是跟随控件里面的内容自动变化控件大小,在可视化的属性里面(Attributes)看到的样子就是这样
匹配约束 Match Constraints
就是根据空间约束的规则来分配剩余空间,有三种模式,分别是spread,percent,wrap,通过layout_constraintHeight_default和layout_constraintWidth_default字段来标注是什么属性,一般是spread。从可视化效果来看,就是Match Constraints,如下图,从代码来看就是layout-wight和layout-height都是0,自动是Match Constraints模式。
spread 默认
有点类似于match parent,不过match parent是相对于父控件,而Match Constraints是相对于约束控件来说,从可视化的属性里面(Attributes)来看,TextView2开始和结束是相对于父控件而已,所以当wight是Match Constraints的时候,宽会填满整个父控件,而高虽然是相对于父控件,底部是相对于TextView1的top,当高变成Match Constraints的时候,会占据父控件Top到TextView1的top,效果如下图
而此时,如果看代码其实TextView2的layout-wight和layout-height都是0,就自动是Match Constraints,而且是layout_constraintHeight_default和layout_constraintWidth_default加不加效果一样
percent:按照父布局百分比设置
控件的尺寸是按照父控件的尺寸的百分比居中限制,需要和layout_constraintHeight_percent|layout_constraintWidth_percent配合使用,如图,TextView是父控件就是ConstraintLayout,100%应该是ConstraintLayout一样大小。代码中layout_constraintHeight_percent|layout_constraintWidth_percent都是0.5,按照ConstraintLayout的50%显示,并且居中
wrap:匹配内容大小但是不超过约束的限制
就是能按照内容大小去匹配,并且不能超过约束的配置,主要是对比layout_width = "wrap_content"|layout_height = "wrap_content"来的。
如下面代码,tv1和tv2都是一样的大小,包裹1234567789的大小,然后又给了另外一层限制,都是距离左右边距是200dp,看tv1的效果,早就突破了这长度,优先了内容的展示1234567789,实际上距离左右边距没有200dp。(tv1如果想要和tv2一样的效果,可以通过代码app:layout_constrainedWidth="true"|app:layout_constrainedHeight="true"设置)
而tv2,优先保证了保持左右边距是200dp,内容展示不全
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_marginStart="150dp"
android:layout_marginEnd="150dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="1234567789"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<TextView
android:id="@+id/tv2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="150dp"
android:layout_marginEnd="150dp"
app:layout_constraintHeight_default="wrap"
app:layout_constraintWidth_default="wrap"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintWidth_percent="0.5"
android:background="@color/colorAccent"
android:text="1234567789"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
比例宽高
app:layout_constraintDimensionRatio="1:1"|app:layout_constraintDimensionRatio="0.5"可以设置款高比例,但是需要至少款高有一个为0。两种设置方式,1:1代表宽度和高度之间的比率,也可以用0.5等浮点型表示
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:3"
app:layout_constraintHeight_default="wrap"
app:layout_constraintWidth_default="wrap"
android:background="@color/colorAccent"
android:text="1234567789"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果展示是
辅助线 Guidelines
自身设置
可以建立一条辅助线,将控件用于辅助线约束,可以在可视化的界面直接拖拽,通过点击下面小三角来改变约束位置和位置数值
通过代码来看,orientation控制是横还是竖
layout_constraintGuide_begin控制位置,如果是距离开始是位置是layout_constraintGuide_begin,如果是距离结束的位置是layout_constraintGuide_end;如果是变成百分比,是layout_constraintGuide_percent="0.5"
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="206dp" />
其余控件相对位置
就是直接通过layout_constraintBottom_toBottomOf等约束,这次是textView1的结束和guideline1对齐,textView2的开始和guideline1对齐,也就是textView1和textView2分别在guideline1两边
<TextView
android:id="@+id/textView1"
android:layout_width="100dp"
android:layout_height="200dp"
android:background="@color/colorAccent"
android:text="TextView 1"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guideline1"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="100dp"
android:layout_height="200dp"
android:background="@color/colorPrimary"
android:text="TextView2"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline1"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
自动化约束
自动连接 Autoconnect
当开启了Autoconnect的时候,也就是可视化页面上面磁铁的按钮,一般情况下会关闭,拖动控件到合适的位置,会自动添加约束。
推断约束 Infer Constraints
我们可以把控件拖到各自位置,按照想要的布局排好,然后点击Infer Constraints按钮,也就是发光棒的样子的按钮,会自动推断当前页面上控件布局,给所有控件添加约束
基线对齐
可以通过layout_constraintBaseline_toBaselineOf让两个控件几线对齐,比如,我们又text1和text2,text2的开始位置和text1的结束位置对齐,此时,我们加上layout_constraintBaseline_toBaselineOf,可以让text1和text2的基线对齐
角度约束
可以约束某个控件相对于某个控件的角度,比如text2在text1的100dp外90°的方向。0°是正上方,顺时针旋转,所以text2在text1的右边。
代码主要是这个三个
app:layout_constraintCircle="@id/tv1" //目标控件的id
app:layout_constraintCircleAngle="90" //对于目标控件的角度,负数无效
app:layout_constraintCircleRadius="100dp" //到目标控件中间的距离
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv1"
android:background="@color/colorPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text1"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv2"
android:text="Text2"
android:textSize="20sp"
android:background="@color/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintCircle="@id/tv1"
app:layout_constraintCircleAngle="90"
app:layout_constraintCircleRadius="100dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
控件内边距、外边距、GONE Margin
内外边距
这个和别的控件一模一样,主要是通过layout_margin和padding来控制的
GONE Margin
这个属性比较奇怪,当依赖的目标是gone的时候,本目标的GONE Margin才会生效,而且要注意方向,比如设置了layout_constraintTop_toTopOf方向约束,那么layout_goneMarginTop才会生效
如图,依赖的控件没有gone的时候,goneMargin没有效果
等控件tv1隐藏
Barrier(屏障)
这个和基线一样,是个不显示在屏膜上的,可以对多个控件进行一个自动合适的适配
比如下图,ABC三个控件,我希望B是放在A和C的右侧,但是A和C里面的文字不定的,不知道哪个长一点,如果我设定B是在A的右侧,当C过长的时候,可能就覆盖了B,虽然可以使用一个控件包裹AC来完成,但是多了一层,可以使用Barrier
Barrier是一个控件,控件并不显示在页面上, 只是为了约束别的控件,主要有两个属性
<!-- 用于控制Barrier相对于给定的View的位置 -->
app:barrierDirection="top|bottom|left|right|start|end"
<!-- 取值是要依赖的控件的id,Barrier将会使用ids中最大的一个的宽/高作为自己的位置 -->
app:constraint_referenced_ids="id,id"
比如如下代码,需要依赖的控件是tvA,tvB,位于这些控件的end。会根据tvA,tvB自适应,如果tvA比较长,就是tvA后面,tvB比较长,就是tvB后面。
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
app:constraint_referenced_ids="tvA,tvC"
app:barrierDirection="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
效果图如下
可以通过把控件B放在Barrier右侧来实现我们要的功能
Group(组)
就是可以把控件加入一个组,对一组控件进行显示或者隐藏操作,同样不显示在页面上,主要就是通过constraint_referenced_ids="id,id……"将控件Id添加进去
<androidx.constraintlayout.widget.Group
android:visibility="gone"
app:constraint_referenced_ids="tvA,tvB,tvC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Placeholder(占位符)
可以在页面上提前部署一个占位符的控件,通过调用这个占位符的setContent(int id),可以将别的控件移动到占位符控件的位置
<androidx.constraintlayout.widget.Placeholder
android:id="@+id/place"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintEnd_toEndOf="parent" />
Chains(链)
把一系列控件首位相连进行排列,会自动形成链,默认是spread,均分剩余空间,有水平链或者垂直链,代码如下
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="A"
android:textSize="40sp"
app:layout_constraintEnd_toStartOf="@id/tvB"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tvB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="B"
android:textSize="40sp"
app:layout_constraintEnd_toStartOf="@id/tvC"
app:layout_constraintStart_toEndOf="@id/tvA" />
<TextView
android:id="@+id/tvC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="C"
android:textSize="40sp"
app:layout_constraintStart_toEndOf="@id/tvB"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
效果呈现就是三个控件均匀分布
layout_constraintHorizontal_chainStyle和layout_constraintVertical_chainStyle分别对水平和垂直链设置模式,模式可选的值有:spread、packed、spread_inside。
spread:就是默认的均分
packed:所有控件紧贴在一起
spread_inside:两侧的控件贴近两边,剩下的控件均分
链还可以设置权重,通过layout_constraintHorizontal_weight|layout_constraintVertical_weight来设置
代码如下
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvA"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintHorizontal_chainStyle="packed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="A"
android:textSize="40sp"
app:layout_constraintEnd_toStartOf="@id/tvB"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tvB"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintHorizontal_chainStyle="packed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="B"
android:textSize="40sp"
app:layout_constraintEnd_toStartOf="@id/tvC"
app:layout_constraintStart_toEndOf="@id/tvA" />
<TextView
android:id="@+id/tvC"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintHorizontal_chainStyle="packed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="C"
android:textSize="40sp"
app:layout_constraintStart_toEndOf="@id/tvB"
app:layout_constraintEnd_toStartOf="@id/tvD"/>
<TextView
android:id="@+id/tvD"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintHorizontal_chainStyle="packed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="D"
android:textSize="40sp"
app:layout_constraintStart_toEndOf="@id/tvC"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
效果图
Flow 流式布局
一般链约束需要控件首尾相连,但是可以使用Flow,会默认将所有控件约束起来。Flow本身不展示在页面上,也是一种虚拟布局。需要的constraintlayout 2.0才有,如果没有,需要去build.gradle看一下constraintlayout的版本
通过app:constraint_referenced_ids="id1,id2,id3……"等设置要进行布局的控件id
通过app:flow_wrapMode=""来设置排列方式,none是默认,就是连续排列,超出的部分不可见。chian是超出部分自动换行,同行的会平分。aligned是超出部分自动换行,同行会一边靠齐。
通过orientation属性,决定是垂直还是水平。
常规使用如下,TextView的id就是A,B,C,D,E,文本也是,通过Flow的app:constraint_referenced_ids将id添加,app:flow_wrapMode可以写也可以不写,默认就是none。
排列方式:app:flow_wrapMode
none:默认属性,就是连续平分空间的排列,如果超出的部分则不可见,代码如下
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/A"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="A"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/B"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="B"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/C"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="C"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/D"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="D"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/E"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="E"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/F"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="F"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/G"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="G"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/H"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="H"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flow_wrapMode="none"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果图如下
chain:超出部分自动换行,并且所有控件等分
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flow_wrapMode="chain"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H" />
效果图
aligned:超出部分也自动换行,但是不是等分而是靠一边显示
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flow_wrapMode="aligned"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H" />
效果图
排列方向:orientation
通过orientation为horizontal|vertical可以控制是水平还是垂直,orientation为vertical是垂直,默认是水平
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H" />
效果图
间隔距离:flow_horizontalGap|flow_verticalGap
通过flow_horizontalGap|flow_verticalGap可以设置各个控件水平或者垂直的间隔距离,要注意一下是水平还是垂直方向的排列,下面代码,是垂直排列,而且间隔是20dp,可以看到控件不在紧紧贴在一起了。
<androidx.constraintlayout.helper.widget.Flow
app:flow_verticalGap="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H" />
效果图
每条链配置
当flow_wrapMode的值是chian或aligned时,通过flow_horizontalStyle等属性,可以对每条链或者所有链进行配置,有三种模式,和链一样
spread:均分排列
packed:贴在一起居中
spread_inside:紧贴两边,其余的均分
app:flow_horizontalStyle="packed|spread|spread_inside" 所有水平链的配置
app:flow_verticalStyle="packed|spread|spread_inside" 所有垂直链的配置
app:flow_firstHorizontalStyle="packed|spread|spread_inside" 第一条水平链的配置,其他条不生效
app:flow_firstVerticalStyle="packed|spread|spread_inside" 第一条垂直链的配置,其他条不生效
app:flow_lastHorizontalStyle="packed|spread|spread_inside" 最后一条水平链的配置,其他条不生效
app:flow_lastVerticalStyle="packed|spread|spread_inside" 最后一条垂直链的配置,其他条不生效
对齐约束
控件在Flow里面,默认是居中对齐的,但是控件大小不一样,可以设置不同的对齐方式。通过flow_verticalAlign|flow_horizontalAlign来控制。如果是水平链是通过flow_verticalAlign控制,如果是垂直链是通过flow_horizontalAlign控制。下面都是以水平链做展示
top:头部对齐
<androidx.constraintlayout.helper.widget.Flow
app:flow_horizontalGap="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="A,B,C,D,E,F"
app:flow_verticalAlign="top" />
bottom:底部对齐
center:居中对齐
baseline:基线对齐
要注意一下,当其中一个TextView里面的文字F不在中间的时候,是根据F的基线对齐的,如果是都是在中间,和center效果一样
数量约束 flow_maxElementsWrap
可以通过flow_maxElementsWrap = "数量值"来约束一条链最大的数量,需要配合flow_wrapMode属性使用,如下代码,flow_maxElementsWrap约束了一条链最多4个,配合了flow_wrapMode是多的靠一边排列,如是none不行,显示不出效果
<androidx.constraintlayout.helper.widget.Flow
app:flow_horizontalGap="10dp"
app:flow_wrapMode="aligned"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="A,B,C,D,E,F"
app:flow_verticalAlign="center"
app:flow_maxElementsWrap="4"/>
效果图
Layer层布局
本质上而已,这个控件是把可以把别的控件加载在它上面,变成一层一层的,它没办法自己设置位置,设置大小,跟着它上面的层自己调整,它不是虚拟的控件,可以被看见,如果它是最上面一层,会覆盖所有的层。主要也是通过constraint_referenced_ids添加别的层的id。
下面代码,虽然写了Layer的位置和大小,但是全部失效,是跟着A和B控件来的,颜色没有失效,可以看到。Layer是在A和B前面写的,所有在最底层,如果在A和B后面就会覆盖掉A和B。
constraint_referenced_ids的顺序没有任何影响,Layer的顺序就是写控件的顺序。
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.helper.widget.Layer
android:background="@color/colorAccent"
android:layout_width="300dp"
android:layout_height="300dp"
app:constraint_referenced_ids="A,B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/A"
android:layout_width="60dp"
android:layout_height="90dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="A"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/B"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="B"
android:textColor="@color/colorWhite"
android:textSize="25sp"
android:textStyle="bold" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果图
ImageFilterButton & ImageFilterView
这两个控件有点像ImageButton和ImageView的关系,有两个特殊作用,再ImageFilterButton|ImageFilterView中都可以。下面主要用ImageFilterView测试
圆角
可以通过app:roundPercent设置圆角的比例,app:round设置大小
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.utils.widget.ImageFilterView
app:roundPercent="0.5"
app:round="50dp"
android:background="@color/colorAccent"
android:layout_width="100dp"
android:layout_height="100dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
效果图
多层图片
src可以设置第一层图片,altSrc可以再设置一层图片,再src上面,默认是透明的,需要通过crossfade属性来设置,0-1直接的值
效果图如下,第一层图片是Android的图标,第二层图片破了的图片,crossfade是0.5
其余属性调整
warmth属性可以用来调节色温
brightness属性用来调节亮度
saturation属性用来调节饱和度
contrast属性用来调节对比度
这几个属性涉及到美术了,目前不太了解
MockView 原型图软件
这个控件,说可以来画原型图,id就是控件里面的文字,使用很简单
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/MockView"
android:layout_width="100dp"
android:layout_height="100dp"/>
效果如下