控件尺寸
1.固定大小
2.使用wrap_content,可以通过android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度
注意!当ConstraintLayout为1.1版本以下时,使用这些属性需要加上强制约束,如下所示:
app:constrainedWidth=”true”
app:constrainedHeight=”true”
3.使用0dp;官方不推荐在ConstraintLayout中使用match_parent
4.宽高比;
当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比
在设置宽高比的值的时候,还可以在前面加W或H,分别指定宽度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3"指的是 高:宽=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 宽:高=2:3
不写HW,默认为W
5.百分比:
当宽或高设置为0dp且其与约束控件全重叠(如与parent,LeftToLeft,RightTorRight)则可以设置
app:layout_constraintWidth(Height)_default="percent"
app:layout_constraintWidth(Height)_percent="0.3"
来控制大小
控件与父容器相对位置
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<!-- 左上-->
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="左上"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:background="#ff00ff"
/>
<!-- 右上-->
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="右上"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#ff00ff"
/>
<!-- 左下-->
<TextView
android:id="@+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="左下"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:background="#ff00ff"
/>
<!-- 右下-->
<TextView
android:id="@+id/text4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="右下"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#ff00ff"
/>
<!-- 居中或者全屏,哪个属性设置wrap_content或xxdp则居中,设置0dp,match_parent则全屏-->
<TextView
android:id="@+id/text5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Text5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#00ffff"
/>
<!-- 居中长度按比例,设置0dp, 长度按比例-->
<TextView
android:id="@+id/text5_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Text51"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#00ffff"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintWidth_default="percent"
/>
<!-- 右下-->
<TextView
android:id="@+id/text6"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="Text6"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#ffff00"
/>
<!-- 类居中偏移-->
<!-- 属性设置为固定长度除0dp外或者wrap_content;则可用bias来按比例偏移。若是全屏则bias无效;
bias赋一个范围为 0-1 的值,假如赋值为0,则TextView1在布局的最左侧,假如赋值为1,则TextView1在布局的最右侧,假如假如赋值为0.5,则水平居中,假如假如赋值为0.3,则更倾向于左侧
-->
<TextView
android:id="@+id/text7"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Text7"
app:layout_constraintHorizontal_bias="0.1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#00ffff"
/>
<!-- 无论控件居中、按比例居中还是全屏margin设置的偏移值都有效-->
<TextView
android:id="@+id/text8"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Text8"
app:layout_constraintHorizontal_bias="0.1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="10dp"
android:layout_maringRight="20dp"
android:background="#00ffff"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
控件与控件相对位置
1.与控件与父控件相同:另一控件居中,全重叠,左上、右上,左下,右下对齐
2.控件还可以在控件左边(上中下),右边(上中下),上边(左中右),下边(左中右 )
3.如果控件是TextView,还可以通过设置layout_constraintBaseline_toBaselineOf以文本基线对齐
4.角度定位
app:layout_constraintCircle="@+id/TextView1"
app:layout_constraintCircleAngle="120"(角度)
app:layout_constraintCircleRadius="150dp"(距离)
指的是TextView2的中心在TextView1的中心的120度,距离为150dp
角度为顺时针,12点方向为0度。
goneMargin
goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值,属性如下:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
可以理解为:约束对象的对象为gone,则其以goneMarginXXX值来替代
链
实现链:形成链的作一控件都设有左右关联(如果是垂直链则是上下关联),最左或最右则与parent
事例代码如:
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2" />
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
/>
<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent" />
1.链式可以在首个控件设置链的样式:
水平链Key:layout_constraintHorizontal(Vertical)_chainStyle
样式值:
CHAIN_SPREAD —— 展开元素 (默认);
CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent;
CHAIN_PACKED —— 链的元素将被打包在一起。
2.权重链(可以理解为替代LinearLayout的权重)
将要设置填充的控件width/height设置为0dp,然后设置layout_constraintHorizontal(constraintVertical)_weight来占有,如果有多个设置此值,点按点比来。此方与LinearLayout相同,只是没有LinearLayout的父值的weightSum(其实也不需要)
Group
在布局文件中加入Group控件androidx.constraintlayout.widget.Group;然后app:constraint_referenced_ids设置要归为一组(以","分割),然后通过控制Group来控制整组的显示隐藏
屏障(barrier)
有时需要将一个控件置于多个控件的最一边比如如下,C想置A,B的最右边,但A,B的长度不一定,而如果设置为A的右侧或设置为B的右侧都不合适。可以在增加barrier控件,并设置为A,B的右侧屏障
A...End
C....
B.........End
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="Aid,Bid" />
<TextView
android:id="@+id/C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/barrier" />
占位符(Placeholder)
Placeholder控件可以用来做为占位符,在需要的时候可以指定(app:content=id)需要移动此此占位符位置的控件
Guideline
Guildline像辅助线一样,在预览的时候帮助你完成布局(不会显示在界面上)。
Guildline的主要属性:
android:orientation 垂直vertical,水平horizontal
layout_constraintGuide_begin 开始位置
layout_constraintGuide_end 结束位置
layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)
优化(Optimizer)
将控件设置为0dp,ConstraintLayout 将对控件进行 2 次测量
在ConstraintLayout上设置layout_optimizationLevel系统会根据布局做一些优化(?);可通过 |添加以下多个:
barriers:找出屏障所在,并用简单的约束取代它们
direct:优化那些直接连接到固定元素的元素,例如屏幕边缘或引导线,并继续优化直接连接到它们的任何元素。
standard:这是包含 barriers 和 direct 的默认优化级别。
dimensions:目前处于实验阶段,并且可能会在某些布局上出现问题——它会通过计算维度来优化布局传递。
chains:目前正在实验阶段,并计算出如何布置固定尺寸的元素链。
ConstraintSet
1.修改ConstraintLayout子元素
示例1:
ConstraintSet set= new ConstraintSet();
//获取一新的ConstraintLayout
//mConstraintLayout 是你的当前使用的约束布局
set.clone(mConstraintLayout);
//这里是重新设置边距,当然也可以重新设置这个view的任何约束, 参数2的类型,可以点进入方法内部,看源码。
set.setMargin(R.id.id, 1,Utils.dip2px(20));
set.setMargin(R.id.id, 3,imageTopMare+Utils.dip2px(20));
//最后一步就是设置新的ConstraintLayout约束 这个必须设置;
set.applyTo(mConstraintLayout);
示例2:
ConstraintSet set = new ConstraintSet();
set.clone(constraintLayout);
// 或
// set.clone(this, R.layout.main_activity);
set.connect(v1.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM);
set.connect(v2.getId(), ConstraintSet.TOP, v1.getId(), ConstraintSet.BOTTOM, dp2px(16));
set.applyTo(constraintLayout);
注意:
1.当使用ConstraintSet 的时候,你的约束布局里面的所有子view,都必须有个id,不然就会报错 All children of ConstraintLayout must have ids to use ConstraintSet
2.如果有View的隐藏显示操作,务必显示操作View.setVisibility(View.VISIBLE)不要在1、2步中间执行,因为建立约束时,之前的位置约束将可能被改变,从而显示可能失效。
2.实现动画
ConstraintSet mConstraintSet1 = new ConstraintSet(); // create a Constraint Set
ConstraintSet mConstraintSet2 = new ConstraintSet(); // create a Constraint Set
mConstraintSet2.clone(context, R.layout.state2); // get constraints from layout
setContentView(R.layout.state1);
mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);
mConstraintSet1.clone(mConstraintLayout);
public void foo(View view) {
TransitionManager.beginDelayedTransition(mConstraintLayout);
if (mOld = !mOld) {
mConstraintSet1.applyTo(mConstraintLayout); // set new constraints
} else {
mConstraintSet2.applyTo(mConstraintLayout); // set new constraints
}
}
注意:两个布局的控件的id要一样,不一样则不一样的控件不会生效
约束布局ConstraintLayout看这一篇就够了
ConstraintLayout+ConstraintSet实现动画效果
ConstraintLayout约束布局使用ConstraintSet修改某个子view