ConstraintLayout Barrier Group Guideline Placeholder

本文深入解析Android ConstraintLayout的使用技巧,涵盖定位、居中、链、虚拟帮助对象等核心功能,帮助开发者灵活布局,提升应用界面设计效率。

ConstraintLayout基本用法

 

非常高兴你能看见我的文章,本文是官方文档根据自己的理解而编写,请阅读我的文章,再次阅读官方文档,传送门https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout提高自我学习能力,若有不当之处,请花费你的宝贵时间,留下建议。

ConstraintLayout的属性组-具有类似功能的属性,分组学习属性

match_parent属性值不推荐使用了,使用0dp替换,在0dp时,控件大小会根据约束来测量

1.Relative positioning-这些属性和RelativeLayout的属性类似,具体属性如下:

  • 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的功能,

举例:app:layout_constraintLeft_toLeftOf="@id/蓝色id",需求-红色left对齐蓝色的left(左对齐)

属性解读第一个left指蓝色-第二个left指红色

<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="40dp"
    android:layout_marginTop="40dp"
    android:background="@color/colorPrimaryDark"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/tv_2"
    android:layout_width="40dp"
    android:layout_height="30dp"
    android:background="@color/colorAccent"
    app:layout_constraintBottom_toBottomOf="@id/tv_1"
    app:layout_constraintLeft_toLeftOf="@id/tv_1"
    app:layout_constraintTop_toTopOf="@id/tv_1" />

 

<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="40dp"
    android:layout_marginTop="40dp"
    android:background="@color/colorPrimaryDark"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/tv_2"
    android:layout_width="40dp"
    android:layout_height="30dp"
    android:background="@color/colorAccent"
    app:layout_constraintBottom_toBottomOf="@id/tv_1"
    app:layout_constraintLeft_toRightOf="@id/tv_1"
    app:layout_constraintTop_toTopOf="@id/tv_1" />

 

layout_constraintBaseline_toBaselineOf  以文字的基准线对齐,所有都是以第一行文字

<TextView
    android:id="@+id/tv_1"
    android:layout_width="50dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/dp_30"
    android:background="@color/colorPrimaryDark"
    android:text="aaaaaaaaaaaaaaaaaa"
    android:textColor="@color/c_ffffff"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />


<TextView
    android:layout_width="50dp"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryDark"
    android:text="bbbbbbbbbbbbbbbbbbb"
    android:textColor="@color/c_ffffff"
    app:layout_constraintLeft_toRightOf="@id/tv_1" 
    app:layout_constraintBaseline_toBaselineOf="@id/tv_1"/>

 

2.Margins,属性组如下

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom

这是我们都知道的外边距,和以前的用法相同,但是若是设定了如android:layout_marginLeft,就必须要有控件左边的约束,Relative positioning的属性,不然外边距将不起作用,其他边距类似,同一边对同一边约束  左-左  右-右  等

 

3.Margins when connected to a GONE widget控件隐藏后的需求

控件B约束依赖于A,控件B相对控件A隐藏后,为了美观和需求,为控件B再添加一种外边距,不同于layout_margin,最后的外边距是他们的和

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

 

<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="40dp"
    android:layout_marginTop="40dp"
    android:background="@color/colorPrimaryDark"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:visibility="gone"/>

<TextView
    android:id="@+id/tv_2"
    android:layout_width="40dp"
    android:layout_height="30dp"
    android:background="@color/colorAccent"
    android:layout_marginLeft="@dimen/dp_30"
    app:layout_constraintBottom_toBottomOf="@id/tv_1"
    app:layout_constraintLeft_toRightOf="@id/tv_1"
    app:layout_constraintTop_toTopOf="@id/tv_1" />

 

举例:没隐藏之前

隐藏之后,细节发现红色块变小了,若是再放一个同样大小的红色方块,比较发现高度只有以前下面的一半,为什么是一半,下节讲解,那是因为上面的一半看不见了,窗口顶到顶部了,所有需要layout_goneMargin属性

设置相应layout_goneMargin属性后,完全显示出来了

 

当控件B的位置是相对于控件B的时候,若是A突然GONE 了,A将变成一位置(坐标)A的所有layout_margin外边距将失效,B的约束都会依赖此(坐标),但是需求界面就会不好看,上面这些属性就是为了解决隐藏之后,为其添加隐藏边距

4.Centering positioning and bias居中的需求

当同一方向水平/垂直 左约束  和  右约束    都是同一控件或parent,那他将被居中显示,其实可以理解为中线对齐

在3小节中,蓝红就是中线对齐,A控件被隐藏后中线就是本身,所以B就只会显示一半

和父布局中线对其

<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="60dp"
    android:layout_marginTop="40dp"
    android:background="@color/colorPrimaryDark"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>

与控件中线对齐,在3小节中就是控件中线对齐

但为什么是中线对齐?  这个中线也是可以控制的

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias
<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="60dp"
    android:layout_marginTop="40dp"
    android:background="@color/colorPrimaryDark"
    app:layout_constraintHorizontal_bias="0"  0-1默认0.5 中线
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

5.Circular positioning 以元的方式对齐

  • layout_constraintCircle 圆心
  • layout_constraintCircleRadius :半径
  • layout_constraintCircleAngle : 角度 (0 to 360)  以时钟方向为正

 

 

<TextView
    android:id="@+id/tv_4"
    android:layout_width="@dimen/dp_30"
    android:layout_height="@dimen/dp_30"
    android:layout_marginTop="@dimen/dp_100"
    android:background="@drawable/s_colorprimarydark"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tv_1" />

<TextView
    android:id="@+id/tv_5"
    android:layout_width="@dimen/dp_30"
    android:layout_height="@dimen/dp_30"
    android:layout_marginTop="@dimen/dp_100"
    android:background="@drawable/s_coloraccent"
    app:layout_constraintCircle="@id/tv_4"
    app:layout_constraintCircleAngle="45"
    app:layout_constraintCircleRadius="@dimen/dp_100"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />  这个为什么要加上不知,不加约束编辑器报错

6.对于控件的宽高的值 

对于ConstraintLayout 自身,  有需求必须嵌套等时

对应宽高设为wrap_content时,和以前一样,可使用下面的属性来限制

  • android:minWidth 
  • android:minHeight 
  • android:maxWidth
  • android:maxHeight 

对于ConstraintLayout的孩子,内部view

具体的宽高值,如100dp-值是多大就多大

自适应宽高WRAP_CONTENT-包裹控件

根据约束来的0dp(MATCH_CONSTRAINT)-根据控件的width根据左右约束,高根据上下约束的对应关系,也是自动测量

情景1

使用WRAP_CONTENT,然后中线对齐

 

由于红色的高是WRAP_CONTENT,当红色不断变大,那么红色的高将大于蓝色的

需求确实不能大于蓝色块,最大和蓝色一样,下面的属性将解决此问题(注意:有时预览有问题)可以理解为宽、高最大值不能超过约束宽高的大小,true不能,false可以

  • app:layout_constrainedWidth=”true|false”
  • app:layout_constrainedHeight=”true|false”
<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="50dp"
    android:layout_marginTop="@dimen/dp_30"
    android:background="@color/colorPrimaryDark"
    android:textColor="@color/c_ffffff"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:layout_width="50dp"
    android:layout_height="wrap_content"
    android:background="@color/colorAccent"
    android:ellipsize="end"
    android:text="bbbbbbbbbbbbbbbbbbbbbbbbbbb"
    android:textColor="@color/c_ffffff"
    app:layout_constrainedHeight="true"
    app:layout_constraintBottom_toBottomOf="@id/tv_1"
    app:layout_constraintLeft_toRightOf="@id/tv_1"
    app:layout_constraintTop_toTopOf="@id/tv_1" />

 

 

情景2

宽或高设为0dp(MATCH_CONSTRAINT)时,默认的宽高将根据约束完全对其约束的宽高,但是有时又有需求限定其宽高

  • layout_constraintWidth_min and layout_constraintHeight_min : 
  • layout_constraintWidth_max and layout_constraintHeight_max :
  • layout_constraintWidth_percent and layout_constraintHeight_percent

7.Percent dimension百分比宽高

要使用百分比宽高需要把对应的宽高设置为MATCH_CONSTRAINT (0dp)

宽高都为0.18  (0-1)

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintWidth_default="percent"
    app:layout_constraintWidth_percent="0.18"
    app:layout_constraintHeight_default="percent"
    app:layout_constraintHeight_percent="0.18"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:background="@color/colorPrimary"/>

 

8.Ratio宽高成比列

宽高以比列的形式测量,至少需要一边设置为0dp,然后添加下面的属性

layout_constraintDimensionRatio

他的值可以为小数也可以为width:height

<TextView
    android:layout_width="100dp"
    android:layout_height="0dp"
    android:background="@color/colorPrimary"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintDimensionRatio="1:1"/>

上面中,只有高度是不确定的,所以 width/height=1/1能够得出结果,若是控件的宽高都设置为0dp,那就不知道该以那边为准了

所以值将引入这种格式app:layout_constraintDimensionRatio="W,width:height",这将以高为准,按比例求宽,若是W换为H,将是求高

 

8.Chains链

链,多个控件在同一方向(水平、垂直)的约束

控件A添加约束,并且A添加右约束向B,B添加指向A的左约束,B添加右约束,形成链

 

<TextView
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="50dp"
    android:layout_marginTop="@dimen/dp_30"
    android:background="@color/colorPrimaryDark"
    android:textColor="@color/c_ffffff"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" 
    app:layout_constraintRight_toLeftOf="@id/tv_2"/>

<TextView
    android:id="@+id/tv_2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorAccent"
    android:ellipsize="end"
    android:text="bbbbbbbbbbbbbbbbb"
    android:textColor="@color/c_ffffff"
    app:layout_constraintBottom_toBottomOf="@id/tv_1"
    app:layout_constraintLeft_toRightOf="@id/tv_1"
    app:layout_constraintTop_toTopOf="@id/tv_1" 
    app:layout_constraintRight_toRightOf="parent"/>

默认的方式,剩余的空间将平均分配,还有其他方式,在链头添加属性layout_constraintHorizontal_chainStyle or layout_constraintVertical_chainStyle 

控件宽高为具体值时或wrap_content有下面的建议

在使用全局居中packed chain时,又形成了居中,可以使用bias属性

控件宽或高为0dp时,默认将0dp的控件平均分配其他空间

 

 

还可以用layout_constraintHorizontal_weight and layout_constraintVertical_weight调整控件的weight比列

 

9.Virtual Helper objects虚拟帮助对象

Barrier-与多个控件的某边对齐

由于a和b都是wrap_content,所以宽根本不能确定,而c又要求同时在a和b右边,所以需要一个虚拟对象Barrier,其他方向同理

<TextView
    android:id="@+id/tv_1"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_marginTop="@dimen/dp_30"
    android:background="@color/colorPrimaryDark"
    android:textColor="@color/c_ffffff"
    android:text="aaaaaaaaaaaa"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/tv_2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="@color/colorAccent"
    android:ellipsize="end"
    android:text="bbbbbbbbbbbbbbbbb"
    android:textColor="@color/c_ffffff"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tv_1" />

<android.support.constraint.Barrier
    android:id="@+id/p_12"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:barrierDirection="end"
    app:constraint_referenced_ids="tv_1,tv_2"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@id/p_12"
    app:layout_constraintTop_toTopOf="@id/tv_1"
    app:layout_constraintBottom_toBottomOf="@id/tv_2"
    android:text="cccccccccc"
    android:background="@color/colorPrimaryDark"/>

Guideline

 

那个虚线是不存在的,只是为了预览,假设左边有边距,有很多控件都需要,每个都去添加外边距,有了更改,又每个都去更改,这将增加很大的工作量,直接添加一个左边的虚拟对象作为边距

 

<android.support.constraint.Guideline
    android:id="@+id/p_left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintGuide_begin="20dp"  简化约束 并且还有自己的独有属性
    android:orientation="vertical"/>

<TextView
    android:id="@+id/tv_1"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_marginTop="@dimen/dp_30"
    android:background="@color/colorPrimaryDark"
    android:textColor="@color/c_ffffff"
    android:text="aaaaaaaaaaaa"
    app:layout_constraintLeft_toLeftOf="@id/p_left"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/tv_2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="@color/colorAccent"
    android:ellipsize="end"
    android:text="bbbbbbbbbbbbbbbbb"
    android:textColor="@color/c_ffffff"
    app:layout_constraintLeft_toLeftOf="@id/p_left"
    app:layout_constraintTop_toBottomOf="@id/tv_1" />

其他功能自己组合,

Group控件集合

由于现在布局扁平化,嵌套减少,我们经常会有多个控件改变状态的visibility,group将多个控件组合,调用group的方法,就会自动去改变group的集合里面的控件状态

  <android.support.constraint.Group
              android:id="@+id/group"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:visibility="visible"
              app:constraint_referenced_ids="button4,button9" />

 

 

ConstraintLayout 2.0 是 Android 布局系统中一个重要的更新版本,它在原有 ConstraintLayout 的基础上引入了多种新工具和实用程序,以提升布局的灵活性、性能以及开发效率。以下是一些主要的新功能和工具: ### 1. MotionLayout MotionLayout 是 ConstraintLayout 2.0 中引入的核心新特性之一。它是一个用于构建复杂动画的布局容器,继承自 ConstraintLayout,并提供了声明式的动画机制。通过 MotionScene XML 文件定义动画状态之间的过渡,可以实现页面滑动、按钮点击反馈、视图变换等多种交互效果。 例如,使用 MotionLayout 可以轻松地将两个约束状态之间的过渡动画化,而无需手动编写复杂的动画代码。这使得开发者能够快速创建流畅的 UI 动画体验[^3]。 ### 2. Barrier Barrier 是一种新的虚拟视图,它可以动态地根据一组子视图的位置来调整自身的位置。Barrier 主要用于解决多个视图对齐的问题,例如当多个 TextView 的宽度不固定时,Barrier 可以确保其他视图始终位于这些 TextView 的右侧。 ```xml <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="textView1,textView2" /> ``` ### 3. Group Group 是一种用于管理多个视图可见性的工具。它可以同时控制一组视图的可见性状态(如 GONE 或 VISIBLE),从而简化了需要批量操作视图可见性的场景。 ```xml <androidx.constraintlayout.widget.Group android:id="@+id/group" android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids="button1,button2" /> ``` ### 4. Placeholder Placeholder 是一种占位符控件,可以在运行时动态地将其他视图放置到指定位置。Placeholder 提供了一种灵活的方式来实现动态布局切换,而不需要重新加载整个布局。 ```xml <androidx.constraintlayout.utils.widget.Placeholder android:id="@+id/placeholder" android:layout_width="wrap_content" android:layout_height="wrap_content" app:content="@id/target_view" /> ``` ### 5. Flow Flow 是 ConstraintLayout 2.0 中新增的一种布局辅助工具,属于 `ConstraintLayout Helpers` 模块的一部分。它允许开发者将一组视图按照水平或垂直方向排列,并支持自动换行。Flow 类似于 HTML 中的 Flexbox 布局,适用于需要动态排列多个子视图的场景。 ```xml <androidx.constraintlayout.helper.widget.Flow android:id="@+id/flow" android:layout_width="0dp" android:layout_height="wrap_content" app:constraint_referenced_ids="view1,view2,view3" app:flow_wrapMode="chain" app:flow_horizontalBias="0.5" app:flow_verticalAlign="top" /> ``` ### 6. Guideline 和 Vertical/Horizontal Chain 的增强 虽然 Guideline 在之前的版本中已经存在,但在 ConstraintLayout 2.0 中其功能得到了进一步增强,例如支持百分比定位和动态调整。此外,Chain 的配置选项也更加丰富,支持更复杂的链式布局需求。 ### 7. Layer Layer 是一种用于管理一组视图的视觉层级的工具。它可以对一组视图进行统一的缩放、旋转、透明度等变换操作,适用于需要整体调整视图组外观的场景。 ```xml <androidx.constraintlayout.helper.widget.Layer android:id="@+id/layer" android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids="image1,image2" app:layer_rotation="45" app:layer_scaleX="1.5" app:layer_scaleY="1.5" /> ``` ### 8. 性能优化与调试工具 ConstraintLayout 2.0 还引入了一些性能优化和调试工具,例如改进的测量逻辑、减少不必要的绘制操作,以及提供更多的布局调试信息。这些改进有助于开发者更好地理解和优化布局性能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值