ConstraintLayout基本用法
非常高兴你能看见我的文章,本文是官方文档根据自己的理解而编写,请阅读我的文章,再次阅读官方文档,传送门https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout提高自我学习能力,若有不当之处,请花费你的宝贵时间,留下建议。
ConstraintLayout的属性组-具有类似功能的属性,分组学习属性
match_parent属性值不推荐使用了,使用0dp替换,在0dp时,控件大小会根据约束来测量
1.Relative positioning-这些属性和RelativeLayout的属性类似,具体属性如下:
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
这些属性功能为继承RelativeLayout的功能,
举例:app:layout_constraintLeft_toLeftOf="@id/蓝色id",需求-红色left对齐蓝色的left(左对齐)
属性解读第一个left指蓝色-第二个left指红色
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_marginTop="40dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_2"
android:layout_width="40dp"
android:layout_height="30dp"
android:background="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="@id/tv_1"
app:layout_constraintLeft_toLeftOf="@id/tv_1"
app:layout_constraintTop_toTopOf="@id/tv_1" />
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_marginTop="40dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_2"
android:layout_width="40dp"
android:layout_height="30dp"
android:background="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="@id/tv_1"
app:layout_constraintLeft_toRightOf="@id/tv_1"
app:layout_constraintTop_toTopOf="@id/tv_1" />
layout_constraintBaseline_toBaselineOf 以文字的基准线对齐,所有都是以第一行文字
<TextView
android:id="@+id/tv_1"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_30"
android:background="@color/colorPrimaryDark"
android:text="aaaaaaaaaaaaaaaaaa"
android:textColor="@color/c_ffffff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:text="bbbbbbbbbbbbbbbbbbb"
android:textColor="@color/c_ffffff"
app:layout_constraintLeft_toRightOf="@id/tv_1"
app:layout_constraintBaseline_toBaselineOf="@id/tv_1"/>
2.Margins,属性组如下
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
这是我们都知道的外边距,和以前的用法相同,但是若是设定了如android:layout_marginLeft,就必须要有控件左边的约束,
Relative positioning的属性,不然外边距将不起作用,其他边距类似,同一边对同一边约束 左-左 右-右 等
3.Margins when connected to a GONE widget控件隐藏后的需求
控件B约束依赖于A,控件B相对控件A隐藏后,为了美观和需求,为控件B再添加一种外边距,不同于layout_margin,最后的外边距是他们的和
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_marginTop="40dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"/>
<TextView
android:id="@+id/tv_2"
android:layout_width="40dp"
android:layout_height="30dp"
android:background="@color/colorAccent"
android:layout_marginLeft="@dimen/dp_30"
app:layout_constraintBottom_toBottomOf="@id/tv_1"
app:layout_constraintLeft_toRightOf="@id/tv_1"
app:layout_constraintTop_toTopOf="@id/tv_1" />
举例:没隐藏之前
隐藏之后,细节发现红色块变小了,若是再放一个同样大小的红色方块,比较发现高度只有以前下面的一半,为什么是一半,下节讲解,那是因为上面的一半看不见了,窗口顶到顶部了,所有需要layout_goneMargin属性
设置相应layout_goneMargin属性后,完全显示出来了
当控件B的位置是相对于控件B的时候,若是A突然
GONE 了,A将变成一位置(坐标)A的所有layout_margin外边距将失效,B的约束都会依赖此(坐标),但是需求界面就会不好看,上面这些属性就是为了解决隐藏之后,为其添加隐藏边距
4.Centering positioning and bias居中的需求
当同一方向水平/垂直 左约束 和 右约束 都是同一控件或parent,那他将被居中显示,其实可以理解为中线对齐
在3小节中,蓝红就是中线对齐,A控件被隐藏后中线就是本身,所以B就只会显示一半
和父布局中线对其
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="40dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
与控件中线对齐,在3小节中就是控件中线对齐
但为什么是中线对齐? 这个中线也是可以控制的
layout_constraintHorizontal_bias
layout_constraintVertical_bias
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="40dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintHorizontal_bias="0" 0-1默认0.5 中线
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
5.Circular positioning 以元的方式对齐
layout_constraintCircle
圆心layout_constraintCircleRadius
:半径layout_constraintCircleAngle
: 角度 (0 to 360) 以时钟方向为正
<TextView
android:id="@+id/tv_4"
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_100"
android:background="@drawable/s_colorprimarydark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_1" />
<TextView
android:id="@+id/tv_5"
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_100"
android:background="@drawable/s_coloraccent"
app:layout_constraintCircle="@id/tv_4"
app:layout_constraintCircleAngle="45"
app:layout_constraintCircleRadius="@dimen/dp_100"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" /> 这个为什么要加上不知,不加约束编辑器报错
6.对于控件的宽高的值
对于ConstraintLayout
自身, 有需求必须嵌套等时
对应宽高设为wrap_content时,和以前一样,可使用下面的属性来限制
android:minWidth
android:minHeight
android:maxWidth
android:maxHeight
对于ConstraintLayout的孩子,内部view
具体的宽高值,如100dp-值是多大就多大
自适应宽高WRAP_CONTENT-包裹控件
根据约束来的0dp(MATCH_CONSTRAINT)-根据控件的width根据左右约束,高根据上下约束的对应关系,也是自动测量
情景1
使用WRAP_CONTENT,然后中线对齐
由于红色的高是WRAP_CONTENT,当红色不断变大,那么红色的高将大于蓝色的
需求确实不能大于蓝色块,最大和蓝色一样,下面的属性将解决此问题(注意:有时预览有问题)可以理解为宽、高最大值不能超过约束宽高的大小,true不能,false可以
app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_marginTop="@dimen/dp_30"
android:background="@color/colorPrimaryDark"
android:textColor="@color/c_ffffff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:ellipsize="end"
android:text="bbbbbbbbbbbbbbbbbbbbbbbbbbb"
android:textColor="@color/c_ffffff"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="@id/tv_1"
app:layout_constraintLeft_toRightOf="@id/tv_1"
app:layout_constraintTop_toTopOf="@id/tv_1" />
情景2
宽或高设为0dp(MATCH_CONSTRAINT)时,默认的宽高将根据约束完全对其约束的宽高,但是有时又有需求限定其宽高
layout_constraintWidth_min
andlayout_constraintHeight_min
:layout_constraintWidth_max
andlayout_constraintHeight_max
:layout_constraintWidth_percent
andlayout_constraintHeight_percent
7.Percent dimension百分比宽高
要使用百分比宽高需要把对应的宽高设置为MATCH_CONSTRAINT
(0dp)
宽高都为0.18 (0-1)
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.18"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.18"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/colorPrimary"/>
8.Ratio宽高成比列
宽高以比列的形式测量,至少需要一边设置为0dp,然后添加下面的属性
layout_constraintDimensionRatio
他的值可以为小数也可以为width:height
<TextView
android:layout_width="100dp"
android:layout_height="0dp"
android:background="@color/colorPrimary"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintDimensionRatio="1:1"/>
上面中,只有高度是不确定的,所以 width/height=1/1能够得出结果,若是控件的宽高都设置为0dp,那就不知道该以那边为准了
所以值将引入这种格式app:layout_constraintDimensionRatio="W,width:height",这将以高为准,按比例求宽,若是W换为H,将是求高
8.Chains链
链,多个控件在同一方向(水平、垂直)的约束
控件A添加约束,并且A添加右约束向B,B添加指向A的左约束,B添加右约束,形成链
<TextView
android:id="@+id/tv_1"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_marginTop="@dimen/dp_30"
android:background="@color/colorPrimaryDark"
android:textColor="@color/c_ffffff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_2"/>
<TextView
android:id="@+id/tv_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:ellipsize="end"
android:text="bbbbbbbbbbbbbbbbb"
android:textColor="@color/c_ffffff"
app:layout_constraintBottom_toBottomOf="@id/tv_1"
app:layout_constraintLeft_toRightOf="@id/tv_1"
app:layout_constraintTop_toTopOf="@id/tv_1"
app:layout_constraintRight_toRightOf="parent"/>
默认的方式,剩余的空间将平均分配,还有其他方式,在链头添加属性layout_constraintHorizontal_chainStyle
or layout_constraintVertical_chainStyle
控件宽高为具体值时或wrap_content有下面的建议
在使用全局居中packed chain时,又形成了居中,可以使用bias属性
控件宽或高为0dp时,默认将0dp的控件平均分配其他空间
还可以用layout_constraintHorizontal_weight
and layout_constraintVertical_weight调整控件的weight比列
9.Virtual Helper objects虚拟帮助对象
Barrier-与多个控件的某边对齐
由于a和b都是wrap_content,所以宽根本不能确定,而c又要求同时在a和b右边,所以需要一个虚拟对象Barrier,其他方向同理
<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginTop="@dimen/dp_30"
android:background="@color/colorPrimaryDark"
android:textColor="@color/c_ffffff"
android:text="aaaaaaaaaaaa"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:ellipsize="end"
android:text="bbbbbbbbbbbbbbbbb"
android:textColor="@color/c_ffffff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_1" />
<android.support.constraint.Barrier
android:id="@+id/p_12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="tv_1,tv_2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/p_12"
app:layout_constraintTop_toTopOf="@id/tv_1"
app:layout_constraintBottom_toBottomOf="@id/tv_2"
android:text="cccccccccc"
android:background="@color/colorPrimaryDark"/>
Guideline
那个虚线是不存在的,只是为了预览,假设左边有边距,有很多控件都需要,每个都去添加外边距,有了更改,又每个都去更改,这将增加很大的工作量,直接添加一个左边的虚拟对象作为边距
<android.support.constraint.Guideline
android:id="@+id/p_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintGuide_begin="20dp" 简化约束 并且还有自己的独有属性
android:orientation="vertical"/>
<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginTop="@dimen/dp_30"
android:background="@color/colorPrimaryDark"
android:textColor="@color/c_ffffff"
android:text="aaaaaaaaaaaa"
app:layout_constraintLeft_toLeftOf="@id/p_left"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:ellipsize="end"
android:text="bbbbbbbbbbbbbbbbb"
android:textColor="@color/c_ffffff"
app:layout_constraintLeft_toLeftOf="@id/p_left"
app:layout_constraintTop_toBottomOf="@id/tv_1" />
其他功能自己组合,
Group控件集合
由于现在布局扁平化,嵌套减少,我们经常会有多个控件改变状态的visibility,group将多个控件组合,调用group的方法,就会自动去改变group的集合里面的控件状态
<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="button4,button9" />