约束布局ConstraintLayout

约束布局ConstraintLayout国际惯例 官网参考文档是最好的学习资料 使用 ConstraintLa 构建自适应界面 1 背景约束布局 ConstraintLa 是最受欢迎的 Jetpack 库之一 其实是 AndroidStudi 2 中主要的新增功能之一 也是 Google 在 2016 年的 I O 大会上重点宣传的一个功能 AS 已经将它作为新建页面默认布局了 经历这几年的迭代 功能已经非常的成熟 现在 2 0 正式版本也发布了 也许你已熟悉了旧版本中的功能 并开始用它来快速构建复杂的页面布局 而新版本除了包

国际惯例,官网参考文档是最好的学习资料:

使用 ConstraintLayout 构建自适应界面

一,背景

约束布局 ConstraintLayout,也有人把它称作“增强型的相对布局”,扁平式的布局方式,无任何嵌套,减少布局的层级,优化渲染性能。是最受欢迎的 Jetpack 库之一,其实是 Android Studio 2.2 中主要的新增功能之一,也是 Google 在2016年的 I/O 大会上重点宣传的一个功能。AS 已经将它作为新建页面默认布局了。经历这几年的迭代,功能已经非常的成熟,现在 2.0 正式版本也发布了,也许你已熟悉了旧版本中的功能,并开始用它来快速构建复杂的页面布局,而新版本除了包含旧版本中的所有功能之外,还在 AS 中集成了可以直接预览 XML 的工具,甚至可以直接在预览界面中对布局进行编辑。

二,控件优点

ConstraintLayout 可以理解为 RelativeLayout + LinearLayout 的混合强化版,同时新版 Android Studio 的布局编辑器也提供了对 ConstraintLayout 完善的编辑支持。使用 ConstraintLayout 可以很方便地在一个层级上实现复杂的布局,功能也很完善,是 Android 官方目前非常重视的一个 Layout(替代以前的 RelativeLayout),使用 ConstraintLayout 后基本可以抛弃 LinearLayout 和 RelativeLayout 的使用,完全不需要任何嵌套就可以实现复杂的 UI,使用起来特别清爽。减少了很多的嵌套的层级,这样 View 在渲染的时候,减少了很多多余的 measurelayout 的开销,如果嵌套的层次越多,提升的效果越明显。

感兴趣的话看官方给出的性能测试示例:解析ConstraintLayout的性能优势

三,项目中引入

如需在项目中使用ConstraintLayout,请按以下步骤操作:

  1. 确保你的maven.google.com代码库已在模块级build.gradle文件中声明:
repositories { 
     google() } 
  1. 将该库作为依赖项添加到同一个build.gradle文件中,如以下示例所示。请注意,最新版本可能与示例中显示的不同:
dependencies { 
     implementation "androidx.constraintlayout:constraintlayout:2.0.4" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha05" } 
  1. 在工具栏或同步通知中,点击 Sync Project with Gradle Files

现在,你可以使用 ConstraintLayout 构建布局。

四,基本使用

4.1 相对位置

要在ConstraintLayout 中确定 view 的位置,必须至少添加一个水平和垂直的约束。每一个约束表示到另一个 view、父布局或者不可见的参考线的连接或者对齐。如果水平或者垂直方向上没有约束,那么其位置就是0。

下面是 ConstraintLayout 确定位置的属性,这些属性的值即可以是 parent(父布局),也可以是某个 view 的 id,和同类型的RelativeLayout属性很相似:

ConstraintLayout RelativeLayout 作用
layout_constraintLeft_toLeftOf layout_alignLeft 与参照控件左对齐
layout_constraintLeft_toRightOf layout_toRightOf 在参照控件的右边
layout_constraintRight_toLeftOf layout_toLeftOf 在参照控件的左边
layout_constraintRight_toRightOf layout_alignRight 与参照控件右对齐
layout_constraintTop_toTopOf layout_alignTop 与参照控件上对齐
layout_constraintTop_toBottomOf layout_below 在参照控件底部
layout_constraintBottom_toTopOf layout_alignBottom 在参照控件的上部
layout_constraintBottom_toBottomOf layout_above 与参照控件下对齐
layout_constraintBaseline_toBaselineOf layout_alignBaseline 与参照控件基线对齐
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf

说明:这里 start/end 一般情况下和 left/right 是一样的效果,主要是为了做国际化适配,方便从右往左读的语言文字(如阿拉伯文)。

一个简单的页面:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左对齐" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="右对齐" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="水平居中" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="垂直居中" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="底部对齐" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent"/> <Button 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"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

在这里插入图片描述
居中显示:

 
     app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" 

水平方向的相对位置:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_center" 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"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Left_toLeftOf" app:layout_constraintBottom_toTopOf="@id/btn_center" app:layout_constraintLeft_toLeftOf="@id/btn_center"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Right_toLeftOf" app:layout_constraintBottom_toTopOf="@id/btn_center" app:layout_constraintRight_toLeftOf="@id/btn_center"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Right_toRightOf" app:layout_constraintRight_toRightOf="@id/btn_center" app:layout_constraintTop_toBottomOf="@id/btn_center"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Left_toRightOf" app:layout_constraintLeft_toRightOf="@id/btn_center" app:layout_constraintTop_toBottomOf="@id/btn_center"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 
 
     <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="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_center" android:layout_width="wrap_content" android:layout_height="100dp" android:text="竖直参照物" 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="Top_toTopOf" app:layout_constraintTop_toTopOf="@id/btn_center" app:layout_constraintRight_toLeftOf="@id/btn_center"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bottom_toTopOf" app:layout_constraintBottom_toTopOf="@id/btn_center" app:layout_constraintRight_toLeftOf="@id/btn_center"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Top_toBottomOf" 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:text="Bottom_toBottomOf" app:layout_constraintLeft_toRightOf="@id/btn_center" app:layout_constraintBottom_toBottomOf="@id/btn_center"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

4.2 尺寸约束

view 中使用 warp_content 或者固定值等等是没有问题的。但是在 ConstraintLayout 中不推荐使用 match_parent 这个值,如果需要实现跟 match_parent 同样的效果,可以使用 0dp 来代替,其表示 match_parent,即适应约束。其跟 match_parent 还是有区别的,后面的例子(宽高比那一小节)会提到。
我们来看下例子:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="wrap_content" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:id="@+id/btn_1" android:layout_width="180dp" android:layout_height="wrap_content" android:text="具体数值:180dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/btn_center"/> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:text="0dp(match_parent)" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/btn_1"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

在这里插入图片描述

4.3 宽高比 Ratio

ConstraintLayout 中,还可以将宽定义成高的一个比例或者高定义成宽的比率。首先,需要将宽或者高设置为0dp(即match_parent),即要适应约束条件。然后通过 layout_constraintDimensionRatio 属性设置一个比率即可。这个比率可以是一个浮点数,表示宽度和高度之间的比率;也可以是“宽度:高度”形式的比率。比如:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="0dp" android:layout_marginTop="30dp" app:layout_constraintTop_toTopOf="parent" android:text="-------------------宽高比2:1-------------------" app:layout_constraintDimensionRatio="2:1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

在这里插入图片描述
如果宽和高都设置为0dp(match_parent),那么 layout_constraintDimensionRatio 的值需要先加一个”W,”或者”H,”来表示约束宽度或高度。如下:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="H,16:9" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

4.4 百分比宽高 Percent

ConstraintLayout 还能使用百分比来设置 view 的宽高。要使用百分比,宽或高同样要设置为 0dp(match_parent)。然后设置以下属性即可:

app:layout_constraintWidth_default="percent" //设置宽为百分比,可以设置percent、spread和wrap app:layout_constraintWidth_percent="0.3" //0到1之间的值,为占父布局宽度的多少 app:layout_constraintHeight_default="percent" //设置高为百分比,可以设置percent、spread和wrap app:layout_constraintHeight_percent="0.3" //0到1之间的值,为占父布局宽度的多少 

例子如下:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:text="宽50%" app:layout_constraintWidth_default="percent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintWidth_percent="0.5"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

注:在早期版本中必需手动指定 app:layout_constraintWidth_default=“percent”,在之后的版本中如果设置了app:layout_constraintWidth_percent 属性,则可以不用指定。

You can also define one dimension of a widget as a ratio of the other one. In order to do that, you need to have at least one constrained dimension be set to 0dp (i.e., MATCH_CONSTRAINT), and set the attribute layout_constraintDimensionRatio to a given ratio

意思是说约束布局支持子控件设置宽高比,前提条件是至少需要将宽高中的一个设置为0dp。为了约束一个特定的边,基于另一个边的尺寸,可以预先附加W,或H以逗号隔开。

4.5 偏移量 bias

如果想让view的位置偏向某一侧,可以使用以下的两个属性来设置:

layout_constraintHorizontal_bias //水平偏向 layout_constraintVertical_bias //竖直偏向 

其值同样也是0到1之间。比如,以下例子为横向偏向左侧30%,默认的居中效果就是50%:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左边偏向30%" app:layout_constraintHorizontal_bias="0.3" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

4.6 圆形定位 Circular positioning

以一个控件为圆心设置角度和半径定位

  • layout_constraintCircle:关联另一个控件,将另一个控件放置在自己圆的半径上,会和下面两个属性一起使用
  • layout_constraintCircleRadius:圆的半径
  • layout_constraintCircleAngle:圆的角度

4.7 权重 weight

LinearLayout中可以设置权重,ConstraintLayout 同样也有这个属性。通过设置以下两个属性:

app:layout_constraintHorizontal_weight //水平权重 app:layout_constraintVertical_weight //竖直权重 

然后将相连的 view 两两约束好即可。如下:

 
     <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="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="权重为1" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/btn_2"/> <Button android:id="@+id/btn_2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="权重为2" app:layout_constraintHorizontal_weight="2" app:layout_constraintLeft_toRightOf="@id/btn_1" app:layout_constraintRight_toLeftOf="@id/btn_3"/> <Button android:id="@+id/btn_3" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintHorizontal_weight="2" android:text="权重为2" app:layout_constraintLeft_toRightOf="@id/btn_2" app:layout_constraintRight_toRightOf="parent"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

在这里插入图片描述

4.8 辅助线 Guideline

Guideline 可以用来辅助布局,通过 Guideline 能创建出一条水平线或者垂直线,该线不会显示到界面上,但是能够利用这些线条来添加约束去完成界面的布局。

Guideline主要的属性有:

android:orientation="horizontal|vertical" app:layout_constraintGuide_begin="30dp" app:layout_constraintGuide_end="30dp" app:layout_constraintGuide_percent="0.5"  
     

来看个例子:

 
     <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="match_parent" android:layout_height="match_parent"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline_h" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.5"/> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline_v" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.5"/> <Button app:layout_constraintLeft_toLeftOf="@id/guideline_v" app:layout_constraintTop_toTopOf="@id/guideline_h" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="辅助线定位"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

4.9 屏障 Barrier

Barrier,直译为障碍、屏障。在约束布局中,可以使用属性constraint_referenced_ids属性来引用多个带约束的组件,从而将它们看作一个整体,Barrier 的介入可以完成很多其他布局不能完成的功能。

 
     <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="match_parent" android:layout_height="match_parent" android:padding="20dp"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:" app:layout_constraintBottom_toBottomOf="@+id/et_name" app:layout_constraintTop_toTopOf="@+id/et_name"/> <TextView android:id="@+id/tv_contract" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="联系方式:" app:layout_constraintBottom_toBottomOf="@+id/et_contract" app:layout_constraintTop_toTopOf="@+id/et_contract"/> <EditText android:id="@+id/et_name" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="请输入姓名" app:layout_constraintLeft_toLeftOf="@+id/barrier" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> <EditText android:id="@+id/et_contract" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="请输入联系方式" app:layout_constraintLeft_toLeftOf="@+id/barrier" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/et_name"/> <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="tv_name,tv_contract"/>  
      androidx.constraintlayout.widget.ConstraintLayout> 

barrierDirection 指定方向,constraint_referenced_ids引用的控件 id(多个id以逗号隔开)。

4.10 Group

Group用于控制多个控件的可见性。使用非常简单,若 android:visibility="gone" 那么 btn1,btn2 控件都会隐藏。

<androidx.constraintlayout.widget.Group android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="visible" app:constraint_referenced_ids="btn1,btn2"> <Button android:id="@+id/btn1" android:text="btn1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btn2" android:text="btn2" android:layout_width="wrap_content" android:layout_height="wrap_content"/>  
      androidx.constraintlayout.widget.Group> 

4.11 隐藏边距 goneMargin

当约束目标的可见性为View.GONE时,还可以通过以下属性设置不同的边距值:

layout_goneMarginStart layout_goneMarginEnd layout_goneMarginLeft layout_goneMarginTop layout_goneMarginRight layout_goneMarginBottom 

4.12 链 Chains

上面这种将相连的 view 两两约束好的实际上就形成了链。在 ConstraintLayout 中可以实现各种不同的链,权重链是其中一种。整个链由链中的第一个view(链头)上设置的属性控制。

  • Spread:视图是均匀分布的(在考虑外边距之后)。这是默认值。
  • Spread inside:第一个和最后一个视图固定在链两端的约束边界上,其余视图均匀分布。
  • Weighted:当链设置为 spread 或 spread inside 时,您可以通过将一个或多个视图设置为“match_parent”(0dp) 来填充剩余空间。默认情况下,设置为“match_parent”的每个视图之间的空间均匀分布,但您可以使用 layout_constraintHorizontal_weight 和 layout_constraintVertical_weight 属性为每个视图分配重要性权重。如果您熟悉线性布局中的 layout_weight 的话,就会知道该样式与它的原理是相同的。因此,权重值最高的视图获得的空间最大;相同权重的视图获得同样大小的空间。
  • Packed:视图打包在一起(在考虑外边距之后)。 然后,您可以通过更改链的头视图偏差调整整条链的偏差(左/右或上/下)。
layout_constraintHorizontal_chainStyle // 横向约束链 layout_constraintVertical_chainStyle // 纵向约束链 

五,ConstraintLayout 2.0 新特性

官方更新文档:What’s New in 2.1

5.1 新增VirtualLayouts:Flow布局

Flow布局是Chains的强化版,是一种新的VirtualLayouts。用于构建流式排版效果:当出现空间不足时,可自动换行或自动延展到屏幕的另一区域。即当需要对多个View进行流式布局 / 不确定其布局空间的实际尺寸时,就可使用Flow布局。
在这里插入图片描述
使用步骤:




  1. 通过属性constraint_referenced_ids获取要引用的视图;
  2. 根据这些视图创建一个虚拟的virtual view group;
  3. 对这些视图进行流式布局。
<androidx.constraintlayout.helper.widget.Flow app:constraint_referenced_ids="a1,a2,a3" app:flow_wrapMode="aligned" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> 

核心属性:flow_wrapMode,用于控制元素的排列方式。
wrapMode
属性说明如下:




<androidx.constraintlayout.helper.widget.Flow app:constraint_referenced_ids="a1,a2,a3" app:flow_wrapMode="aligned" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" />  
     

5.2 可自定义ConstraintHelper

ConstraintHelper 是一个用于记录标记 Views 的 Helper,通过引用指定 Views 从而实现具体效果。

使用场景

  • 辅助布局:创建一个新的布局方式,避免创建新的 ViewGroup 从而加深层级
  • 修改布局:在布局完成后,修改布局效果
  • 重新渲染:在View绘制完成后,对View进行修改、重新渲染效果

具体使用:通过继承 ConstraintHelper 类实现 & 重写所需回调,具体如下所示。

// 继承ConstraintHelper类 class carsonhoTest @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : ConstraintHelper(context, attrs, defStyleAttr) { 
     // 复写常用方法 override fun updatePostLayout(container: ConstraintLayout?) { 
     super.updatePostLayout(container) getViews(container).forEach { 
     view -> ViewAnimationUtils.createCircularReveal( view, view.width / 3, view.height / 3, 0f, hypot((view.height / 3.0), (view.width / 3.0)).toFloat() ).apply { 
     duration = 2000 start() } } } } // 常用方法说明 init() // 初始化调用 updatePreLayout() // 布局前更新 updatePostLayout() // 布局后更新 updatePostMeasure() // 测量后更新 updatePostConstraints() // 更新约束 onDraw() // 进行绘制 

5.3 新增切换状态布局功能:ConstraintLayoutStates

ConstraintLayoutStates 用于根据状态切换不同的布局文件。

具体使用

// 步骤1:创建不同状态的layout xml文件,布局文件的root id相同即可。 // 如:states_1、states_2 // 步骤2:在xml文件夹下创建管理文件  
     <ConstraintLayoutStates xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <State android:id="@+id/state1" app:constraints="@layout/states_1" /> <State android:id="@+id/state2" app:constraints="@layout/states_2" />  
      ConstraintLayoutStates> 
// 步骤3:使用loadLayoutDescription来加载管理文件 val constraintLayout = findViewById<ConstraintLayout>(R.id.constraint_state) constraintLayout.loadLayoutDescription(R.xml.constraint_layout_states) constraintLayout.setOnClickListener { 
     // 点击时切换布局文件 constraintLayout.setState(R.id.state2, 0, 0) } 

5.4 新增创建约束工具类:ConstraintProperties

ConstraintProperties 是在代码中创建约束的工具类。
具体使用:在该工具类出来前,修改属性的常用方式是:

ConstraintSet().apply { 
     clone(constraintLayout) setTranslationX(R.id.xxx, 32f) setMargin(R.id.xxx, ConstraintSet.START, 42) applyTo(constraintLayout) } 

对于 ConstraintLayoutStates,可使用流式 API 修改属性,更加方便快捷。

ConstraintProperties(findViewById(R.id.xxx)) .translationZ(8f) .margin(ConstraintSet.START, 8) .apply() 

PS. 推荐阅读

  • 使用 ConstraintLayout 构建自适应界面【官方文档】
  • 解析ConstraintLayout的性能优势【Google 开发者计划工程师 Takeshi Hagikura】
  • Android新特性介绍,ConstraintLayout完全解析【郭霖,拖拽动图讲解】
  • ConstraintLayout 完全解析,快来优化你的布局吧【张鸿洋】
  • 自律给你自由——设计布局的新姿势【徐宜生】
  • ConstraintLayout使用场景必知必会【徐宜生】
  • 带你了解Android约束布局ConstraintLayout【四月葡萄】
  • ConstraintLayout使用指南
  • 妙用ConstraintLayout的Circular positioning【进阶实战,按钮展开效果】
  • 实战篇ConstraintLayout的崛起之路
  • android ConstraintLayout使用详解
  • ConstraintLayout的使用教程
  • ConstraintLayout 2.0 新特性详解及实战
  • 约束布局ConstraintLayout看这一篇就够了
  • ConstraintLayout看完一篇真的就够了么?
  • 布局优化:9种让你不得不使用约束布局Constraintlayout的场景
  • 万字长文 – 史上最全ConstraintLayout(约束布局)使用详解
  • ConstraintLayout使用大全


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/219302.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午10:53
下一篇 2026年3月17日 下午10:53


相关推荐

  • python3 zipfile_Python之zipfile模块的使用[通俗易懂]

    python3 zipfile_Python之zipfile模块的使用[通俗易懂]1、判断是否是zip文件#!/usr/bin/envpython3#encoding:utf-8importzipfilefilenames=[‘tcp_server.py’,’test.py’,’test.zip’]forfilenameinfilenames:print(‘{:>15}{}’.format(filename,zipfile.is_zipfile(fil…

    2025年12月13日
    11
  • AI+Cursor(AI 原生代码编辑器)

    AI+Cursor(AI 原生代码编辑器)

    2026年3月12日
    2
  • Avro介绍[通俗易懂]

    Avro介绍[通俗易懂]ApacheAvro是一个数据序列化系统。Avro所提供的属性:1.丰富的数据结构2.使用快速的压缩二进制数据格式3.提供容器文件用于持久化数据4.远程过程调用RPC5.简单的动态语言结合功能,Avro和动态语言结合后,读写数据文件和使用RPC协议都不需要生成代码,而代码生成作为一种可选的优化只值得在静态类型语言中实现。Avro的SchemaAvro的Schema用…

    2025年5月23日
    6
  • Spring AOP 切面@Around注解的具体使用

    Spring AOP 切面@Around注解的具体使用@Around注解可以用来在调用一个具体方法前和调用后来完成一些具体的任务。比如我们想在执行controller中方法前打印出请求参数,并在方法执行结束后来打印出响应值,这个时候,我们就可以借助于@Around注解来实现;再比如我们想在执行方法时动态修改参数值等类似功能的注解还有@Before等等,用到了SpringAOP切面思想,SpringAOP常用于拦截器、事务、日志、权限验…

    2022年7月15日
    42
  • Vue项目 在chrome页面崩溃:喔唷 崩溃了(总结)

    Vue项目 在chrome页面崩溃:喔唷 崩溃了(总结)情况一 vue 项目在谷歌浏览器上出现崩溃一 问题描述 最近 vue 项目开发时 在 chrome 浏览器页面过一段时间一直提示 页面崩溃 喔唷崩溃了项目开发的时候 测试同事反馈页面会出现 喔唷崩溃了 打开控制台进行相同操作后发现控制台会频繁出现一个警告 Forcedreflow N ms 二 问题 N

    2026年3月19日
    2
  • flash 外国小游戏教程网站[通俗易懂]

    flash 外国小游戏教程网站[通俗易懂]http://www.tutorialized.com/tutorial/game-tutorial-part-1-character-movement/44240  相关的小游戏制作教程:有兴趣可以看看 http://www.emanueleferonato.com/2007/05/15/create-a-flash-racing-game-tutorial/

    2025年7月4日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号