【达内课程】布局控件之 ConstraintLayout
文章目录
- 介绍
- 基本使用
- Attributes
- 属性
- 辅助工具
-
- Guideline
- 自动添加约束
- Group
- Placeholder
- Barrier
- ConstraintSet 使用,动态修改约束布局
介绍
约束布局 ConstraintLayout 是一个 ViewGroup,可以在 Api9 以上的 Android 系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件,ConstraintLayout 非常适合使用可视化的方式来编写界面。从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout。
ConstraintLayout 官方文档
基本使用
添加依赖
app/build.gradle 文件中添加 ConstraintLayout 的依赖
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
添加约束
新建一个空项目,Android Studio会自动帮我们创建好一个布局,默认使用 ConstraintLayout
我们将 xml 切换到 Design 模式。现在主操作区域内有两个类似于手机屏幕的界面,左边的是预览界面,右边的是蓝图界面。这两部分都可以用于进行布局编辑工作,区别是左边部分主要用于预览最终的界面效果,右边部分主要用于观察界面内各个控件的约束情况。
如果我们想让 Button 位于布局的右下角,可以进行如下操作:
首先从左侧的 Palette 区域拖一个 Button 进去,可以看到 Button 的上下左右各有一个圆圈,这圆圈就是用来添加约束的。每个控件的约束都分为垂直和水平两类,一共可以在四个方向上给控件添加约束。我们给 Button 的右边和下边添加了约束,因此 Button 就会将自己定位到布局的右下角了。
如果想让 Button 居中,就需要给它的上下左右都添加约束:
除此之外,我们还可以使用约束让一个控件相对于另一个控件进行定位。比如说,我们希望再添加一个 Button,让它位于第一个 Button 的正下方,并且间距 84dp:
删除约束
第一种用于删除一个单独的约束,将鼠标悬浮在某个约束的圆圈上,然后该圆圈会变成同心圆,这个时候单击一下,约束线变成实线后,按下键盘上的 Del 键即可删除
第二种用于删除某一个控件的所有约束,选中一个控件,右键 -> Clear Constraints of Selection
第三种用于删除当前界面中的所有约束,点击工具栏中的删除约束图标即可:
Attributes
选中任意一个控件的时候,在右侧的 Attributes 区域就会出现很多的属性选项
在这里可以设置当前控件的所有属性,这里不再进行详细介绍,自己操作一下就知道了。下面介绍 Layout 这一部分内容
我们可以看到有一个纵向的轴和一个横向的轴,这两个轴也是用于确定控件的位置的。我们让第一个 Button 居中显示了,其实就是因为这里纵横轴的值都是50。如果调整了纵横轴的比例,那么Button的位置也会随之改变:
正方形区域,它是用来控制控件大小的。正方形周围输入框能控制边距。中间的符号一共有三种模式可选,每种模式都使用了一种不同的符号表示,点击符号即可进行切换。
表示 wrap_content,此时可以使用下列属性来控制最大、最小的高度或宽度:
android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度
注意!当 ConstraintLayout 为 1.1 版本以下时,使用这些属性需要加上强制约束,如下所示:
app:constrainedWidth=”true”
app:constrainedHeight=”true”
表示固定大小
表示any size,它有点类似于 match parent,但和 match_parent 并不一样,是属于 ConstraintLayout 中特有的一种大小控制方式,下面我们来重点讲解一下。
首先需要说明,在 ConstraintLayout 中是有 match_parent 的,只不过用的比较少,因为 ConstraintLayout 的一大特点就是为了解决布局嵌套,既然没有了布局嵌套,那么 match_parent 也就没有多大意义了。所以官方不推荐在 ConstraintLayout 中使用 match_parent,可以设置 0dp (MATCH_CONSTRAINT) 配合约束代替 match_parent。
我们将 Button 的宽度指定成any size,它就会自动充满整个布局了:
这和 match_parent 有什么区别呢?其实最大的区别在于,match_parent 是用于填充满当前控件的父布局,而any_size是用于填充满当前控件的约束规则。举个例子更好理解,如果我们有一个新的 Button,它的其中一个约束是添加到当前这个 Button 上的,那么any_size的效果也会发生改变:
我们切换到code 模式看下代码中是如何写的
<?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">
<Button
android:id="@+id/button10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button13"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button10" />
</androidx.constraintlayout.widget.ConstraintLayout>
属性
- 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
这些属性根据名字就很容易知道它们的意思。
举例:实现以下效果
<?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"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
android:text="TextView1" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView2"
...
app:layout_constraintLeft_toRightOf="@+id/tv1" />
<TextView
android:id="@+id/tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView3"
...
app:layout_constraintTop_toBottomOf="@+id/tv1" />
</androidx.constraintlayout.widget.ConstraintLayout>
layout_constraintLeft_toRightOf
对于一个View的边界界定,官方给了下面这张图:
一般情况下只是用 layout_constraintLeft_toRightOf 效果是这样的:
如图所示,两个 TextView 的高度不一致,但是又希望他们文本对齐,这个时候就可以使用 layout_constraintBaseline_toBaselineOf
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:background="#D8BFD8"
android:gravity="center"
android:text="TextView1" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:background="#DDA0DD"
android:text="TextView2"
app:layout_constraintBaseline_toBaselineOf="@+id/tv1"
app:layout_constraintLeft_toRightOf="@+id/tv1" />
角度定位
角度定位指的是可以用一个角度和一个距离来约束两个空间的中心
上面例子中的 TextView2 使用以下3个属性:
app:layout_constraintCircle="@+id/tv1"
app:layout_constraintCircleAngle="120"(角度)
app:layout_constraintCircleRadius="150dp"(距离)
TextView2 的中心在TextView1的中心的 120度,距离为 150dp
边距
ConstraintLayout 的边距常用属性如下:
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_
lingorare: 请问在marketplace中install时一直报错 Problems occurred while performing provisioning operation: operation plan must be resolved,说是JustJ OpenJDK Host JRE Complete和kotlin冲突,该怎么办呢?
number007cool: 我cygcheck -c cygwin 检查是安装成功的,但是gcc g++ 都没有,该怎么装
number007cool: linux 下的动态库,在cygwin下能被正常使用么
Yl33944: 请问为什么按照步骤安装但是在验证时显示No setup information found
qq_66112157: 我安装的cygwin,运行全部是英文版本,我如何将其变为中文版本?