ConstraintLayout约束布局
ConstraintLayout有啥好处呢?可以减少布局层次,特别适合复杂的大型布局。可谓是集线性布局和相对布局于一身的荣誉布局。
使用
添加依赖
目前,AndroidStudio新的版本默认就给你上ConstraintLayout了。如果没有的话怎么添加以来呢?
repositories {
google()
}
添加仓库依赖
dependencies {
implementation ‘com.android.support.constraint:constraint-layout:1.1.2’
}
然后就sync一下就好了。
把现有的布局转成约束布局
在 Android Studio 中打开您的布局,然后点击编辑器窗口底部的 Design 标签。
在 Component Tree 窗口中,右键点击该布局,然后点击 Convert layout to ConstraintLayout。
一、创建约束布局的规则
- 每个视图都必须至少有两个约束条件:一个水平约束条件,一个垂直约束条件(不进行水平或者垂直约束的话,默认显示到0,0位置也就是左上角)
- 只能在共用同一平面的约束手柄与定位点之间创建约束条件。因此,视图的垂直平面(左侧和右侧)只能约束在另一个垂直平面上;而基准线则只能约束到其他基准线上。(简单说视图顶部/底部只能约束顶部或底部,左侧/右侧只能约束左侧或右侧)
- 每个约束句柄只能用于一个约束条件,但您可以在同一定位点上创建多个约束条件(从不同的视图),也就是说出发只能一个而到达目的地可以多个
二、布局
相对布局
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布局很相似,表示谁在谁的地方,比如:
- 相对与父级
<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"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> androidx.constraintlayout.widget.ConstraintLayout>
比如说这样子,顶部相对于父级的顶部约束,开始的位置跟父级开始的位置一样。
这里的 app:layout_constraintStart_toStartOf="parent"也可以换成 app:layout_constraintLeft_toLeftOf=“parent”
但是他们俩还是有所区别的
left一定是左边,而start不一定,我们的习惯是start从左往右,比如说文字阅读。而某些国家是start从右往左。这个开始方向是跟系统语言有关系的。
- 同级的相对布局
<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" 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:text="button2" app:layout_constraintLeft_toLeftOf="@id/button" app:layout_constraintTop_toBottomOf="@id/button" />
还有baseLine基线线
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button2" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBaseline_toBaselineOf="@id/button"/>
2.角度定位
相关属性
//围绕的目标
layout_constraintCircle
//距离
layout_constraintCircleRadius
//角度
layout_constraintCircleAngle
比如:
<Button android:id="@+id/earth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是地球" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="13dp" android:layout_marginBottom="51dp" android:text="我是月亮" app:layout_constraintBottom_toTopOf="@+id/earth" app:layout_constraintCircle="@id/earth" app:layout_constraintCircleAngle="45" app:layout_constraintCircleRadius="120dp" app:layout_constraintStart_toEndOf="@+id/earth" />
3.绝对布局
用于设置控件在ConstraintLayout中并未约束的绝对位置。运行后在真机上是看不到的,只能做到Design时进行预览。
相关属性
layout_editor_absoluteX
layout_editor_absoluteY
例如按钮在x,y的绝对坐标为120dp,如果已经约束的话,绝对布局就不起作用了
4.margin
相关属性
当前View与另一个View绑定后,另一个View的属性设置为了Gone,则以下属性会生效
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
layout_goneMarginStart
layout_goneMarginEnd
<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"> <Button android:id="@+id/earth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="100dp" android:layout_marginLeft="100dp" android:text="我是地球" android:visibility="gone" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="@id/earth" app:layout_constraintTop_toBottomOf="@id/earth" android:text="我是月亮" app:layout_goneMarginTop="100dp" app:layout_goneMarginLeft="100dp" />androidx.constraintlayout.widget.ConstraintLayout>
因为textView的左部和顶部绑定Button,所以当button的可见性为gone时app:layout_goneMarginTop=“100dp”
app:layout_goneMarginLeft="100dp"就起作用
偏移
bias就是偏移的意思
相关属性
水平偏移和垂直偏移
layout_constraintHorizontal_bias
layout_constraintVertical_bias
水平方向
<Button android:id="@+id/earth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是地球" app:layout_constraintHorizontal_bias="0.2" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
水平偏移20%
垂直方向
<Button android:id="@+id/earth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是地球" app:layout_constraintVertical_bias="0.2" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" />
垂直方向偏移20%
6.宽高比
相关属性
layout_constraintDimensionRatio
如果我们要一下宽和高为1:2的控件大小
<Button android:id="@+id/earth" android:layout_width="100dp" android:layout_height="0dp" android:text="我是地球" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="1:2" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
宽高至少得有一个为0,则以另外一个值作为参考进行比例。
7.权重
和之前的LinearLayout布局很相似
相关属性
水平方向的权重,垂直方向的权重
layout_constraintHorizontal_weight
layout_constraintVertical_weight
<Button android:id="@+id/button1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="button1" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/button2" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="button2" app:layout_constraintHorizontal_weight="2" app:layout_constraintLeft_toRightOf="@id/button1" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
垂直方向同样的用法
链式布局
相关属性
layout_constraintHorizontal_chainStyle
layout_constraintVertical_chainStyle
- CHAIN_SPREAD 左右两边距离相等
- CHAIN_SPREAD_INSIDE 内边距相关
- Weighted chain 权重链,根据权重占比
- CHAIN_PACKED 两边等距内容一起
- package chain with bias 同上,不过有偏移
例子:
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="A" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/button2" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="B" app:layout_constraintLeft_toRightOf="@id/button1" app:layout_constraintRight_toLeftOf="@id/button3" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="C" app:layout_constraintLeft_toRightOf="@id/button2" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
在链头添加样式:
app:layout_constraintHorizontal_chainStyle=“packed”
app:layout_constraintHorizontal_chainStyle=“spread_inside”
app:layout_constraintHorizontal_chainStyle="spread"
尺寸约束
相关属性
layout_constrainedWidth
layout_constrainedHeight
layout_constraintWidth_default
layout_constraintHeight_default
layout_constraintWidth_min 将设置此维度宽的最小尺寸
layout_constraintWidth_max将设置此维度宽的最大尺寸
layout_constraintWidth_percent将此维度的宽大小设置为父维度的百分比
layout_constraintHeight_min 将设置此维度高的最小尺寸
layout_constraintHeight_max将设置此维度高的最大尺寸
layout_constraintHeight_percent将此维度的高大小设置为父维度的百分比
WRAP_CONTENT (添加在 1 . 1中):强制约束
如果维度设置为WRAP_CONTENT,则在 1.1 之前的版本中,它们将被视为文字维度——也就是说,约束不会限制结果维度。虽然通常这已经足够(并且更快),但在某些情况下,您可能希望使用WRAP_CONTENT,但继续强制执行约束以限制结果维度。在这种情况下,您可以添加相应的属性之一:
app:layout_constrainedWidth=“true|false”
app:layout_constrainedHeight=“true|false”
当app:layout_constrainedWidth=“false”
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="A" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/button2" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="B" app:layout_constraintLeft_toRightOf="@id/button1" app:layout_constraintRight_toLeftOf="@id/button3" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" app:layout_constrainedWidth="false" android:layout_height="wrap_content" android:text="CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" app:layout_constraintLeft_toRightOf="@id/button2" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
当app:layout_constrainedWidth="true"会强制对button3进行约束,并限制维度
layout_constrainedHeight 同理
layout_constraintWidth_default值选项有三,是枚举类型
定义如下:
<attr name="layout_constraintWidth_default"> <enum name="spread" value="0"/> <enum name="wrap" value="1"/> <enum name="percent" value="2"/> </attr>
主要用于设置百分比
1.宽度为0dp或高度为0dp
l2.ayout_constraintWidth_default为percent,或layout_constraintHeight_default为percent
3.通过layout_constraintHeight_percent 或者layout_constraintWidth_percent 来设置百分比
例如:
宽度占0.7,高度为wrap_content
<Button android:id="@+id/button3" android:layout_width="0dp" app:layout_constraintWidth_default="percent" android:layout_height="wrap_content" app:layout_constraintWidth_percent="0.7" android:text="CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" app:layout_constraintLeft_toRightOf="@id/button2" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
最值限定
- layout_constraintWidth_min
- layout_constraintWidth_max
- layout_constraintHeight_min
- layout_constraintHeight_max
若内容是动态内容,此时为包裹内容会动态变化宽高,可以通过设置以上几个属性来限定控件的宽高变化
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintHeight_max="50dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintWidth_max="200dp" />
辅助约束
参考线Guideline
可以理解为一个假设的线,实际运行时不会出现。只是你看预览效果时会有
相关属性
//开始
layout_constraintGuide_begin
//结束
layout_constraintGuide_end
//百分比
layout_constraintGuide_percent
例子:
开始距离
<androidx.constraintlayout.widget.Guideline android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintGuide_begin="100dp"/>
方向,默认是水平方向
<androidx.constraintlayout.widget.Guideline android:layout_width="wrap_content" android:orientation="vertical" android:layout_height="wrap_content" app:layout_constraintGuide_begin="100dp"/>
改成垂直方向,如上
百分比,注意,取值[0,1]f
<androidx.constraintlayout.widget.Guideline android:layout_width="wrap_content" android:orientation="vertical" android:layout_height="wrap_content" app:layout_constraintGuide_percent="0.5"/>
使用,参考于guide_line
右边连接到guide_line的右边
<androidx.constraintlayout.widget.Guideline android:id="@+id/guide_line" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_end="100dp" /> <Button android:id="@+id/earth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是地球" app:layout_constraintRight_toRightOf="@+id/guide_line" app:layout_constraintTop_toTopOf="parent" />
屏障Barrier
举个例子
<TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="30dp" android:text="1111111111111111111" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:padding="30dp" android:text="22222222222" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text1" /> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:text="333333333333333333333333333333333" app:layout_constraintLeft_toRightOf="@id/text1" app:layout_constraintTop_toTopOf="parent" />
左边的1和2都是包裹内容,内容动态添加的话会撑大。目前3是以1的右边作为参考。如果2变大,则会与3重叠
例如出现下面情况,这显然不符合我们的要求,此时需要设置一道屏障,相当于一堵墙
<TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="30dp" android:text="1111111111111111111" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:padding="30dp" android:text="22222222222222222222222222222222222" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text1" /> <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="text1,text2" /> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:text="333333333333333333333333333333333" app:layout_constraintLeft_toRightOf="@id/barrier" app:layout_constraintTop_toTopOf="parent" />
这样子,就以屏障作为参考了
Group组
This class controls the visibility of a set of referenced widgets. Widgets are referenced by being added to a comma separated list of ids,
控制一组内容的可见性
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="30dp" android:text="1111111111111" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="30dp" android:text="22222222222222" app:layout_constraintLeft_toRightOf="@id/button1" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="30dp" android:text="333333333333333" app:layout_constraintLeft_toRightOf="@id/button2" app:layout_constraintTop_toTopOf="parent" /> <androidx.constraintlayout.widget.Group android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids="button1,button3" />
设置不可见
<androidx.constraintlayout.widget.Group android:layout_width="wrap_content" android:visibility="gone" android:layout_height="wrap_content" app:constraint_referenced_ids="button1,button3" />
就只剩下一个button2了。
来源地址:https://blog.csdn.net/ChenYiRan123456/article/details/127017645