[toc]
以前使用ConstraintLayout,只会使用layout_constraintXxx_toXxxOf的属性,虽然知道Guideline, bias,但很少使用。工作中的一个需求,无法通过简单的约束实现,就决定看一下官方文档,更深入的掌握ConstraintLayout。
特殊属性
layout_goneMarginxxx:当前控件参照的视图gone时生效。app:layout_goneMarginLeft="180dp"-
水平偏移
layout_constraintHorizontal_bias:- 同时设置左右约束时,向某侧偏移 (默认:居中)。
- 值在 0~1 之间
- 在约束链(chain)中可能失效
- 例
app:layout_constraintHorizontal_bias="0.2"
-
限制宽度
app:layout_constrainedWidth="true|false"- 仅
wrap_content模式有效 - 默认为false。
- 值为true,且左右约束都设定时:
- 内容宽度超过左右约束,则以约束为准;
- 内容宽度小于左右约束,则使用内容宽度。
- 仅
-
最大宽度
layout_constraintWidth_max- 仅
MATCH_CONSTRAINT (0dp)模式有效 - 值为准确尺寸 或
wrap - 示例
app:layout_constraintWidth_max="200dp" - 另外 android: maxWidth / maxHeight : 只在 wrap_content 时生效。
- 仅
-
最小宽度
layout_constraintWidth_min- 仅
MATCH_CONSTRAINT (0dp)模式有效 - 值为准确尺寸 或
wrap - 值大于约束宽度时仍有效,会超出右侧约束。
- 示例
app:layout_constraintWidth_min="wrap" - 另外 android:minWidth / minHeight : 只在 wrap_content 时生效。
- 仅
-
宽度百分比
layout_constraintWidth_percent-
生效条件:
android:layout_width="0dp"app:layout_constraintWidth_default="percent"
宽度占父控件的百分比
值 0 ~ 1
-
示例
<Button android:id="@+id/btn5" android:text="ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="@id/tv4" app:layout_constraintRight_toRightOf="@id/tv7" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.5" />
-
-
宽高比例
layout_constraintDimensionRatio- 生效条件:宽和高至少一个为
MATCH_CONSTRAINT (0dp)模式 - 设置宽高比例
- 例 W:H = 4:1
app:layout_constraintDimensionRatio="4:1" - 优先级高于约束尺寸:比例计算得宽度大于左右约束空间时,等距离超出左右约束。
- 宽和高都是 0dp 时
- 应确保某一维度得约束是完全的,即同时设定左右约束,或同时设定上下约束。
- 文档中有指定变化维度的方法
"H, 4:1" 或 "W, 4:1",经过试验,某些情况下会出现比例反转。
- 生效条件:宽和高至少一个为
View.GONE : 当控件被设置为GONE时,本身的约束属性(
layout_constraintXxx_toXxxOf)仍然生效,但宽、高、外边距(margin)被置 0 。在布局中仍定位一个点,使依赖它的其他控件能够布局,这些控件或需设置layout_goneMarginxxx属性。
Chain(链)
通过“双向链接”连在一起的一组元素。元素之间双向连接、链两端单向连接。
链头(chain head) : 水平链最左一个元素,竖直链最顶一个元素。某些属性只有在链头元素设置才有效。
-
链样式:
layout_constraintHorizontal_chainStyle和layout_constraintVertical_chainStyle决定剩余空间的分布。-
样式值:
-
spread(伸展)(默认样式) -
spread_inside(内部伸展) -
packed(收缩)
-
-
只能在链头元素设置该属性
img
-
-
水平权重:
layout_constraintHorizontal_weight,竖直权重:layout_constraintVertical_weight- 仅
MATCH_CONSTRAINT (0dp)模式有效 - 分配顺序:优先为
wrap_content控件分配空间,剩余空间按权重分配。如果剩余空间为0,则指定权重的控件尺寸为0。 - 默认权重为0。即两个控件尺寸都为0dp,A控件指定权重,B控件不设置该属性,则B控件实际尺寸为0 。
- 外边距叠加:A控件layout_marginRight="20dp",B控件layout_marginLeft="10dp",则A和B的间距为30dp。
- 示例:
<?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" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/ch1" android:text="111 " android:layout_marginRight="20dp" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/ch2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_weight="2" /> <Button android:id="@+id/ch2" android:text="222 222" android:layout_marginLeft="10dp" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@id/ch1" app:layout_constraintRight_toLeftOf="@id/ch3" app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_weight="1" /> <Button android:id="@+id/ch3" android:text="333 3333333333" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@id/ch2" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout> - 仅

辅助对象
Barrier (边界)
作用:自动跟踪一组视图某个方向的最值,本身不显示。其他控件使用barrier约束位置,可以达到同时参照多个控件的效果。
属性:
-
barrierAllowsGoneWidgets,是否考虑可见性为gone的控件,值为true或false,默认为true。 -
barrierDirection设定跟踪哪个方向的边界,值为left top reght bottom start end。 -
constraint_referenced_ids参照的控件,多个控件 id 逗号隔开。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/text1"
android:text="text1"
android:background="#a0d0f0"
android:singleLine="true"
android:layout_marginTop="60dp"
android:layout_marginLeft="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/text2"
android:text="text2text2"
android:background="#a0d0f0"
android:singleLine="true"
android:layout_marginTop="60dp"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/text1"
/>
<TextView
android:id="@+id/text3"
android:text="text3text3"
android:background="#a0d0f0"
android:singleLine="true"
android:layout_marginTop="90dp"
android:layout_marginLeft="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<android.support.constraint.Barrier
android:id="@+id/barrier1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="text1,text2, text3"
/>
<Button
android:id="@+id/btn1"
android:text="Button1"
android:layout_marginTop="60dp"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/barrier1"
/>
</android.support.constraint.ConstraintLayout>
观察button1位置变化


Guideline (参考线)
作用:为其他控件提供定位,本身不显示。
尺寸:水平Guideline高度为0,宽度适配父控件;竖直Guideline宽度为0,高度适配父控件。Guideline的尺寸是固定的,不能通过layout_width / layout_height改变。
重要属性:
orientation方向,horizontal / vertical。水平Guideline只能提供上下定位,竖直Guideline只能提供左右定位。-
定位,以下三个属性设置一个即可:
layout_constraintGuide_percent,通过百分比定位自身,值为小数 0 ~ 1 。layout_constraintGuide_begin,与父控件左端或顶端的距离。layout_constraintGuide_end,与父控件右端或底端的距离。
Placeholder (占位符)
作用:通过约束属性设置一个位置,可以动态将其他控件移动到这个位置,移动后控件的点击事件等原有属性保留。
定位:定位方式和普通控件相同,通过layout_constraintXxx_toXxxOf 和 margin 定位。
示例:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn1"
android:text="btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="30dp"
/>
<android.support.constraint.Placeholder
android:id="@+id/ph1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_example)
btn1.setOnClickListener {
if(ph1.content != btn1){
ph1.setContentId(btn1.id)
} else{
ph1.setContentId(ph1.id)
}
}
}

Group (组)
作用:控制一组控件的可见性(visibility)。多个Group可以引用同一个控件,按xml文件中的顺序,最后一个Group的可见性最终决定控件的可见性。
属性:constraint_referenced_ids 成员id,多个控件的id用逗号隔开
示例:
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="button4,button9" />
