前言:ConstraintLayout是Google在16年Google I/O大会上与AS 2.2预览版一起发布的新的布局优化方案,去年还没有被大规模使用,但是在今年的面试中有许多公司(包括百度,蔚来,好像还有新浪等等公司在面试的时候,都问过了这个布局,而不再问其他布局,其中百度就问了Constaranit的有点和一个简单的案例实现,还问了ConstraintLayout的四大辅助类(Guideline,Barrier,Chains和Groups)是什么各自的功能。以前没有用过,没有回答上来,最近有时间就系统的学习了一下)
1.ConstraintLayout继承了ViewGroup,可以把它理解成是对RelativeLayout的的优化,从字面意思理解ConstraintLayout是约束布局,其主要目的是减少层级的嵌套,它可以;灵活的定位和调整子View的大小和位置,在一个约束布局中,一般会有一个Souce(源)View以及一个Target(目标)View,Source View的位置通过一定的约束关系依赖于Target View,,这样Source View就和Target View链接在一起了。其中Source View相对于Target View的位置是固定的。
2.ConstraintLayout的基本属性
ConstraintLayout最基本的属性有下面几个,既layout_constraintXXX_toXXXOf格式的属性,也就是说View A的方向XXX置于View B的方向的YYY。当然,ViewB可以是父容器,如果是父容器既Constraintlayout,则使用parent标示。
layout_constraintBaseline_toBaselineOf(View A内部的文字与View B内部的文字对其)
layout_constraintLeft_toLeftOf(View A与View B左对齐)
layout_constraintRight_toLeftOf(View A的右边置于View B的左边)
layout_constraintLeft_toRightOf(View A的左边置于View B的右边)
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopof
layout_constraintBottom_toBottomOf
layout_constraintStart_toStartof
layout_constraintStart_toEndOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
圆形定位
layout_constraintCircle="@+id/XXX"//引用的控件
layout_constraintCircleRadius="XXXdp"//圆的半径
layout_constraintCircleAngle="45"//偏移的圆的角度,水平方向为0,逆时针方向旋转
3.普通的约束(右上,右下,左上,左下)
1.普通实现
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.example.jie.constraintlayout.MainActivity">
<Button
android:id="@+id/btn_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_right_top"
android:text="Right And Top"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintLeft_toRightOf="@id/btn_center"
app:layout_constraintBottom_toTopOf="@id/btn_center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_right_bottom"
android:text="Right And Bottom"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toRightOf="@id/btn_center"
app:layout_constraintTop_toBottomOf="@id/btn_center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_left_top"
android:text="Left And Top"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
app:layout_constraintRight_toLeftOf="@id/btn_center"
app:layout_constraintBottom_toTopOf="@id/btn_center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_left_bottom"
android:text="Left And Bottom"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
app:layout_constraintRight_toLeftOf="@id/btn_center"
app:layout_constraintTop_toBottomOf="@id/btn_center"/>
</android.support.constraint.ConstraintLayout>
2.以角度来实现
圆形定位
layout_constraintCircle="@+id/XXX"//引用的控件
layout_constraintCircleRadius="XXXdp"//圆的半径
layout_constraintCircleAngle="45"//偏移的圆的角度,水平方向为0,逆时针方向旋转
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.example.jie.constraintlayout.MainActivity">
<Button
android:id="@+id/btn_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_right_top"
android:text="Right And Top"
app:layout_constraintCircle="@id/btn_center"
app:layout_constraintCircleRadius="150dp"
app:layout_constraintCircleAngle="45"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_right_bottom"
android:text="Right And Bottom"
app:layout_constraintCircle="@id/btn_center"
app:layout_constraintCircleRadius="150dp"
app:layout_constraintCircleAngle="135"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_left_top"
android:text="Left And Top"
app:layout_constraintCircle="@id/btn_center"
app:layout_constraintCircleRadius="150dp"
app:layout_constraintCircleAngle="225"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_left_bottom"
android:text="Left And Bottom"
app:layout_constraintCircle="@id/btn_center"
app:layout_constraintCircleRadius="150dp"
app:layout_constraintCircleAngle="315"/>
</android.support.constraint.ConstraintLayout>
4.文字对其:layout_constraintBaseline_toBaselineOf(View A内部的文字与View B内部的文字对其)
1.与高度短的对其
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="200dp"
android:text="Source"
android:id="@+id/btn_source"
app:layout_constraintLeft_toRightOf="@id/btn_target"
android:layout_marginLeft="30dp"
app:layout_constraintBaseline_toBaselineOf="@id/btn_target"/>
2.与高度宽的对其
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="75dp"/>
<Button
android:id="@+id/btn_source"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_marginLeft="30dp"
android:text="Source"
app:layout_constraintLeft_toRightOf="@+id/btn_target"/>
5.当source View和target view的相对位置
1.Source和Target都显示
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
android:layout_marginRight="20dp"
app:layout_constraintRight_toLeftOf="@id/btn_source"
/>
<Button
android:id="@+id/btn_source"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintRight_toRightOf="parent"/>
2.Source设为不可见,而target设为可见
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
android:layout_marginRight="20dp"
app:layout_constraintRight_toLeftOf="@id/btn_source"
/>
<Button
android:id="@+id/btn_source"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"/>
3.Source和taeget都可见,target设为app:layout_goneMarginRight="120dp"
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
android:layout_marginRight="20dp"
app:layout_constraintRight_toLeftOf="@id/btn_source"
app:layout_goneMarginRight="120dp"
/>
<Button
android:id="@+id/btn_source"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintRight_toRightOf="parent"/>
4.Source不可见而taeget可见,target设为app:layout_goneMarginRight="120dp"
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
android:layout_marginRight="20dp"
app:layout_constraintRight_toLeftOf="@id/btn_source"
app:layout_goneMarginRight="120dp"/>
<Button
android:id="@+id/btn_source"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintRight_toRightOf="parent"/>
5.如果只有Target View
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
android:layout_marginRight="20dp"
app:layout_goneMarginRight="120dp" />
需要注意的是:
app:layout_goneMarginRight需要配合Android:layout_marginRight一起使用
如果source的可见性设为Gone则控件marginXXX也会被goneMarginXXX替换掉。
6.居中定位和偏向(Centering positioning And bias)
1.居中显示
<Button
android:id="@+id/btn_source"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
2.屏幕居中
<Button
android:id="@+id/btn_source"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
3.偏向
如果搭配偏向,能使约束偏向于某一边,默认是0.5,有以下属性
layout_constraintHorizontal_bias(0-1其中0在最左边,1在最右边)
layout_constraintVertical_bias(0-1其中0在最上边,1在最下边)
例如将layout_constraintHorizontal_bias = 0.9
<Button
android:id="@+id/btn_source"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.9"/>
7.尺寸约束
1.对WRAP_CONTENT和MATCH_PARENT的约束
如果再为ConstraintLayout定制大小时,如果layout_width或者layout_height定义为WRAP_CONTENT和MATCH_PARENT可以定义
android:minwidth
android:maxwidth
android:minheight
android:maxheight
2.控件尺寸约束
控件View的宽和高一般设为三种形式
确定尺寸
WRAP_CONTENT
0dp就等于MATCH_CONSTRAINT
这里需要注意的是官方在ConstraintLayout中已经不再支持MATCH_PAERENT(MATCH_PARENT is not supported for widgets contained in a ConstraintLayout, though similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to “parent”.)
而是通过MATCH_CONSTRAINT替换
<Button
android:layout_width="200dp"
android:layout_height="100dp"
android:text="Button one"
android:id="@+id/btn_1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Two"
android:id="@+id/btn_2"
app:layout_constraintLeft_toLeftOf="@id/btn_1"
app:layout_constraintRight_toRightOf="@id/btn_1"
app:layout_constraintTop_toBottomOf="@id/btn_1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button Three"
android:id="@+id/btn_3"
app:layout_constraintLeft_toLeftOf="@id/btn_2"
app:layout_constraintRight_toRightOf="@id/btn_2"
app:layout_constraintTop_toBottomOf="@id/btn_2"/>
而这里之所以使用了0dp而没有实现宽度撑满屏幕的效果是因为使用Button Three的相对约束对象是Button Two,这里如果把Button three的约束对象设为父布局或者把Button Two的约束设为父布局则Button Three的宽度就可以撑满整个屏幕了。
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button Two"
android:id="@+id/btn_2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button Three"
android:id="@+id/btn_3"
app:layout_constraintLeft_toLeftOf="@id/btn_2"
app:layout_constraintRight_toRightOf="@id/btn_2"
app:layout_constraintTop_toBottomOf="@id/btn_2"/>
<Button
android:layout_width="200dp"
android:layout_height="100dp"
android:text="Button one"
android:id="@+id/btn_1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Two"
android:id="@+id/btn_2"
app:layout_constraintLeft_toLeftOf="@id/btn_1"
app:layout_constraintRight_toRightOf="@id/btn_1"
app:layout_constraintTop_toBottomOf="@id/btn_1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button Three"
android:id="@+id/btn_3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_2"/>
8.比例(Ratio)
1.ConstraintLayout提供了可以只定义一维的约束,这个约束可以是width也可以是height,然后通过属性layout_constraintDimentionRatio设置给定的比例。
例如:
<Button
android:layout_width="200dp"
android:layout_height="0dp"
android:text="Button one"
android:id="@+id/btn_1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="1:2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Two"
android:id="@+id/btn_2"
app:layout_constraintLeft_toLeftOf="@id/btn_1"
app:layout_constraintRight_toRightOf="@id/btn_1"
app:layout_constraintTop_toBottomOf="@id/btn_1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button Three"
android:id="@+id/btn_3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_2"/>
2.当然,也可以将width和height都设为0dp,然后在使用layout_constraintDimensionRatio进行约束
例如将Button的text设为“Button One”,高度是宽度的3倍
<Button
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button One"
android:id="@+id/btn_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="H,3:1"/>
9.填充父窗口约束(MATCH_CONSTRAINT percent)
<Button
android:id="@+id/btn_source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Source"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_percent="0.5"/>
layout_constraintwidth_percent相对于父布局的百分比
常见的其他类似的属性还有
layout_constraintWidth_min | layout_constraitWidth_max:设置宽度的最小值和最大值
layout_constraintHeight_min | layout_constraintHeight_max:设置高度的最小值和最大值
layout_constraintWidth_percent | layout_constraintHeight_percent:设置高度或者宽度所占父布局的百分比
当然,也可以结合约束布局(layout_constraintDimensionRatio)一起使用
如:
<ImageView
android:id="@+id/iv_source"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/girl"
android:scaleType="fitXY"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintDimensionRatio="h,1:1"/>
将layout_constraintWidth_perent设为0.5
<ImageView
android:id="@+id/iv_source"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/girl"
android:scaleType="fitXY"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintWidth_percent="0.5"/>
ConstraintLayout四大辅助类:Guideline,Chains,Barrier和Groups
10.Guideline
在项目开发时,有时需要这个相对的参照物,而这个参照物又不想让它显示在窗口中,例如登录操作登录和注册按钮的对其操作,目前来说使用ConstraintLayout是很难实现的,当然可以实现,但是比较麻烦,这里就需要用到ConstraintLayout提供的一个新的功能Guideline
1)Guideline继承了View,但是在draw()方法中没有做任何的实现。因此即使在布局中添加了这个参数,在界面中也不会显示的。
public class Guideline extends View {
public Guideline(Context context) {
super(context);
super.setVisibility(8);
}
...
public void setVisibility(int visibility) {
}
public void draw(Canvas canvas) {
}
...
}
2)定义两个按钮
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_login"
android:text="登录"
android:padding="5dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_register"
android:text="注册"
android:padding="5dp"/>
3)添加GuideLine
4)登录和注册相对居中显示距离底部64dp,两者相距64dp
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="64dp"
android:layout_marginEnd="32dp"
android:padding="5dp"
android:text="登录"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline3"/>
<Button
android:id="@+id/btn_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="64dp"
android:layout_marginStart="32dp"
android:padding="5dp"
android:text="注册"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"/>
<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="192dp"/>
5).自动添加约束(Autoconnect)
有时布局编写好以后,不想让它的相对位置发生改变,可以使用autoconnect,按钮的位置是发光的笔
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="64dp"
android:layout_marginEnd="32dp"
android:padding="5dp"
android:text="登录"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline3"/>
<Button
android:id="@+id/btn_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="64dp"
android:layout_marginStart="32dp"
android:padding="5dp"
android:text="注册"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"/>
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="241dp"/>
<TextView
android:id="@+id/textView"
android:layout_width="54dp"
android:layout_height="20dp"
android:text="TextView"
app:layout_constraintBaseline_toBaselineOf="@+id/editText"
app:layout_constraintEnd_toEndOf="@+id/textView2"
app:layout_constraintStart_toStartOf="@+id/textView2"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="51dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="42dp"
android:layout_marginRight="20dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintBottom_toTopOf="@+id/editText2"
app:layout_constraintRight_toRightOf="parent"
/>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.498"/>
11.链条(Chains)
ConstraintLayout提供的链条市值在同一条轴上(水平或者竖直)方向提供一个类似群组的统一表现,另外一个轴可以单独控制
创建链条(Creating a chain)
如果source和target双向依赖则可以将他们视为链条
链条的头部是指最左边或者最上边的子View
1.最简单的链
<Button
android:id="@+id/btn_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
app:layout_constraintRight_toLeftOf="@id/btn_source"
app:layout_constraintLeft_toLeftOf="parent"/>
<Button
android:id="@+id/btn_source"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source"
android:layout_marginRight="20dp"
app:layout_constraintLeft_toRightOf="@id/btn_target"
app:layout_constraintRight_toRightOf="parent"/>
2.链条样式(Chain Style)
当一个链条的头部元素设置了属性layout_constraintHorizontal_chainStyle或者layout_constraintVertical_chainStyle时,链条的行为将根据指定的样式(默认是CHAIN_SPREAD)而更改。
1).不设置chainStyle既默认形式(layout_constraintHorizontal_chainStyle="spread")
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:id="@+id/btn_a"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"//这里可以省略,spread是默认形式
app:layout_constraintRight_toLeftOf="@id/btn_b"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:id="@+id/btn_b"
app:layout_constraintLeft_toRightOf="@id/btn_a"
app:layout_constraintRight_toLeftOf="@id/btn_c"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C"
android:id="@+id/btn_c"
app:layout_constraintLeft_toRightOf="@id/btn_b"
app:layout_constraintRight_toRightOf="parent"/>
2).将A的layout_constraintHorizontal_chainStyle设为packed
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:id="@+id/btn_a"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintRight_toLeftOf="@id/btn_b"/>
3).将A的layout_constraintHorizontal_chainStyle设为spread_inside
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:id="@+id/btn_a"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintRight_toLeftOf="@id/btn_b"/>
3.加权链(weighted chains)
如果一个链条中的元素多个元素使用了0dp或者MATCH_CONSTRAINT,则它们将平均使用剩余所占的空间,这是可以使用权值来分配剩余的空间layout_constraintHorizontal_weight和layout_constraintVertical_weight分配剩余空间。例如有A,B,C三个View组成的链条,其中A,B的权重都是2,C的权重是1,则它们展示的View是
<Button
android:id="@+id/btn_a"
android:layout_width="0dp"
android:layout_height="44dp"
android:text="A"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/btn_b"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="B"
android:id="@+id/btn_b"
app:layout_constraintLeft_toRightOf="@id/btn_a"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintRight_toLeftOf="@id/btn_c"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="C"
android:id="@+id/btn_c"
app:layout_constraintLeft_toRightOf="@id/btn_b"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintRight_toRightOf="parent"/>
12.多View的约束:Barrier
1)Barrier和Guideline类似,它继承了ConstraintHelper,而ConstraintHelper继承了View,同时它们两个都没有实现draw()方法,因此它在界面中同样是看不到的,其主要作用是如果其中一个视图增长,则Barrier将其大学调整为所引用项目的最大高度或者宽度。
public abstract class ConstraintHelper extends View {
protected int[] mIds = new int[32];
protected int mCount = 0;
protected Context myContext;
protected Helper mHelperWidget = null;
protected boolean mUseViewMeasure = false;
private String mReferenceIds;
public ConstraintHelper(Context context) {
super(context);
this.myContext = context;
this.init((AttributeSet)null);
}
...
this.mIds[this.mCount] = tag;
++this.mCount;
}
public void onDraw(Canvas canvas) {
}
...
public void updatePostLayout(ConstraintLayout container) {
}
public void updatePostMeasure(ConstraintLayout container) {
}
}
2)在一些表格布局或者中英文切换时,经常会遇到多行,多列的操作,如果使用TableLayout则需要多层的嵌套,如果不适用,有可能就会造成View的覆盖操作
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
tools:layout_editor_absoluteX="30dp"
tools:layout_editor_absoluteY="164dp"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="@string/desc"
app:layout_constraintLeft_toLeftOf="parent"
tools:layout_editor_absoluteY="82dp"/>
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/ttile_text"
tools:layout_editor_absoluteX="114dp"
tools:layout_editor_absoluteY="71dp"/>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/text_hello"
tools:layout_editor_absoluteX="114dp"
tools:layout_editor_absoluteY="155dp"/>
如果所示在英文下还好,
如果切换中文时,就有可能造成View的叠加现象
这时可以使用Barrier进行约束
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
tools:layout_editor_absoluteX="30dp"
tools:layout_editor_absoluteY="164dp"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="@string/desc"
app:layout_constraintLeft_toLeftOf="parent"
tools:layout_editor_absoluteY="82dp"/>
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/ttile_text"
tools:layout_editor_absoluteX="114dp"
tools:layout_editor_absoluteY="71dp"
app:layout_constraintStart_toEndOf="@id/barrier2"/>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/text_hello"
tools:layout_editor_absoluteX="114dp"
tools:layout_editor_absoluteY="155dp"
app:layout_constraintStart_toEndOf="@id/barrier2"/>
<android.support.constraint.Barrier
android:id="@+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView,textView2"/>
此时英文情况下
中文情况下:
13组Group
1)Group几乎和Barrier一样,都是继承与ConstraintHelper,而ConstraintHelper继承与View,两则也没有实现Draw()方法。
ConstraintLayout中组的概念和ViewGroup不一样,ConstraintLayout中组仅仅包含了视图id的引用,而不是将组合中的视图进行嵌套,这样可以通过设置组的可见性就可以实现组中控件的可见性。而无需实现组中每一个元素的可见性。
public abstract class ConstraintHelper extends View {
protected int[] mIds = new int[32];
protected int mCount = 0;
protected Context myContext;
protected Helper mHelperWidget = null;
protected boolean mUseViewMeasure = false;
private String mReferenceIds;
public ConstraintHelper(Context context) {
super(context);
this.myContext = context;
this.init((AttributeSet)null);
}
...
this.mIds[this.mCount] = tag;
++this.mCount;
}
public void onDraw(Canvas canvas) {
}
...
public void updatePostLayout(ConstraintLayout container) {
}
public void updatePostMeasure(ConstraintLayout container) {
}
}
Group相对简单<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
tools:layout_editor_absoluteX="30dp"
tools:layout_editor_absoluteY="164dp"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="@string/desc"
app:layout_constraintLeft_toLeftOf="parent"
tools:layout_editor_absoluteY="82dp"/>
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/ttile_text"
tools:layout_editor_absoluteX="114dp"
tools:layout_editor_absoluteY="71dp"
app:layout_constraintStart_toEndOf="@id/barrier2"/>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/text_hello"
tools:layout_editor_absoluteX="114dp"
tools:layout_editor_absoluteY="155dp"
app:layout_constraintStart_toEndOf="@id/barrier2"/>
<android.support.constraint.Barrier
android:id="@+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView,textView2"/>
<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="textView,textView2"
android:visibility="gone"/>
此时Group中的app:constraint_referenced_ids中关联了textView和 textViwew2,此时将Group的可见性设为gone则textView和textView2也是不可见的。