Android 新控件之ConstraintLayout(约束布局)

ConstraintLayout (约束布局) 继承于ViewGroup 允许开发者以灵活的方式定位和调整小部件的大小

ConstraintLayout 可让开发者使用扁平视图层次结构(无嵌套视图组)创建复杂的大型布局。它与 RelativeLayout 相似,其中所有的视图均根据同级视图与父布局之间的关系进行布局,但其灵活性要高于 RelativeLayout,并且更易于与 Android Studio 的布局编辑器配合使用。我理解为ConstraintLayout是一个更加灵活且减少嵌套的 RelativeLayout的布局

注意:

ConstraintLayout作为支持库提供,开发者可以在从 API 级别 9 (Gingerbread) 开始的 Android 系统上使用。

引用:

    //网络库引用
    implementation "androidx.constraintlayout:constraintlayout:2.1.3"

ConstraintLayout出现的原因???

相信在面对一些复杂的UI页面,咱们都是使用RelativeLayout,LinearLayout层层嵌套实现的.虽然能实现效果.但是层层嵌套层层解析加载View 无疑会耗费加载时间,耗费手机性能.这是时候ConstraintLayout(约束布局),就应运而生了,它出现的目的就是减少嵌套,优化层层嵌套状况带来的弊端

学习:

要在 ConstraintLayout 中定义某个视图的位置,您必须为该视图添加至少一个水平约束条件和一个垂直约束条件。每个约束条件均表示与其他视图、父布局或隐形引导线之间连接或对齐方式。每个约束条件均定义了视图在竖轴或者横轴上的位置;因此每个视图在每个轴上都必须至少有一个约束条件,但通常情况下会需要更多约束条件。

当您将视图拖放到布局编辑器中时,即使没有任何约束条件,它也会停留在您放置的位置。不过,这只是为了便于修改;当您在设备上运行布局时,如果视图没有任何约束条件,则会在位置 [0,0](左上角)处进行绘制。

在图 1 中,布局在编辑器中看起来很完美,但视图 C 上却没有垂直约束条件。在设备上绘制此布局时,虽然视图 C 与视图 A 的左右边缘水平对齐,但由于没有垂直约束条件,它会显示在屏幕顶部


图2.png

图1.png

当前约束类型:

  • 相对定位
  • 边距
  • 圆形定位
  • 可见性行为
  • 尺寸约束
  • 链条
  • 虚拟助手对象
  • 优化器

请注意,约束中不能有循环依赖。

1. 相对定位

相对定位是在 ConstraintLayout 中创建布局的基本构建块之一。这些约束允许您相对于另一个小部件定位给定的小部件。您可以在水平和垂直轴上约束一个小部件:

  • 水平轴:左、右、起点和终点
  • 垂直轴:顶部、底部和文本基线
    例如,为了将按钮 B 定位到按钮 A 的右侧(图 1):


    相对定位示例png.png

如下图,这告诉系统我们希望按钮 B 的左侧被约束到按钮 A 的右侧。这样的位置约束意味着系统将尝试让两侧共享相同的位置。


相对定位约束.png

这是可用约束的列表:

//示例
<Button android:id="@+id/buttonB" ...
                 app:layout_constraintLeft_toLeftOf="parent" />

app:layout_constraintLeft(自身)_toLeftOf(相对于的控件)="相对的控件ID"

layout_constraintLeft_toLeftOf //自身的左边位于相对Id的左边
layout_constraintLeft_toRightOf //自己的右边位于相对id的右边
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

1.2 layout_constraintBaseline_toBaselineOf 基线对齐

  <TextView
        android:id="@+id/TextView1"
        .../>

    <TextView
        android:id="@+id/TextView2"
        ...
        app:layout_constraintLeft_toRightOf="@+id/TextView1" 
        app:layout_constraintBaseline_toBaselineOf="@+id/TextView1"/>
基线对齐.png

2.边距

相对定位边距.png

如果设置了侧边距,它们将应用于相应的约束(如果存在)(图 ),将边距强制为目标端和源端之间的空间。通常的布局边距属性可用于此效果

2.1属性:

android:layout_marginStart //距离开始
android:layout_marginEnd //距离结束
android:layout_marginLeft //距离左边
android:layout_marginTop //距离上边
android:layout_marginRight //距离右边
android:layout_marginBottom //距离下边
layout_marginBaseline //距离基线


请注意,边距只能为正数或等于零,并且取Dimension.

2.2. 约束目标View.GONE的时候 的边距

layout_goneMarginStart //距离开始
layout_goneMarginEnd ....
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
layout_goneMarginBaseline

3.居中定位和偏移

3.1 居中定位,就是把定位控件的左边对应目标的左边 右边对应目标的右边,上边对应目标的上边

//居中展示
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"


居中定位.jpg

居中.png

如上图,Button的左边位于父布局的左边,右边位于父布局的右边就做到了水平居中的效果

3.2 偏移 : 有时候居中展示还需要做出偏移效果

  • layout_constraintHorizontal_bias //水平方向偏移
  • layout_constraintVertical_bias //垂直方向偏移
    效果:
    app:layout_constraintHorizontal_bias="0.3"
    水平方向距父布局开始位置偏移百分之三十
<androidx.constraintlayout.widget.ConstraintLayout ...>
             <Button android:id="@+id/button" ...
                 app:layout_constraintHorizontal_bias="0.3"
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent"/>
</ConstraintLayout >
偏移.png

4.圆形定位

可以以一定角度和距离约束一个小部件中心相对于另一个小部件中心。这允许您将一个小部件定位在一个圆圈上


圆形定位.png
  • layout_constraintCircle : 引用另一个小部件 id
  • layout_constraintCircleRadius : 到另一个小部件中心的距离
  • layout_constraintCircleAngle : 小部件应该在哪个角度(以度为单位,从 0 到 360)
<Button android:id="@+id/buttonA" ... />
  <Button android:id="@+id/buttonB" ...
      app:layout_constraintCircle="@+id/buttonA"
      app:layout_constraintCircleRadius="100dp"
      app:layout_constraintCircleAngle="45" />

5.可见性行为

ConstraintLayout对标记为 的小部件进行了特定处理View.GONE。

GONE像往常一样,小部件不会被显示并且不是布局本身的一部分(即,如果标记为 ,它们的实际尺寸不会改变GONE)。
但就布局计算而言,GONE小部件仍然是其中的一部分,但有一个重要区别:

  • 对于布局通道,它们的尺寸将被视为零(基本上,它们将被解析为一个点)
  • 如果它们对其他小部件有限制,它们仍然会受到尊重,但任何边距都将等于零


    可见性行为.png

    这种特定行为允许构建布局,您可以在其中临时将小部件标记为 is GONE,而不会破坏布局(图 7),这在制作简单布局动画时特别有用。

注意:
使用的边距将是 B 在连接到 A 时定义的边距(参见图 7 示例)。在某些情况下,这可能不是您想要的边距(例如,A 到其容器的一侧有 100dp 的边距,B 到 A 的边距只有 16dp,将 A 标记为已消失,B 到容器的边距为 16dp)。出于这个原因,您可以指定在连接到被标记为已消失的小部件时使用的备用边距值(请参阅上面有关已消失的边距属性的部分

6.尺寸约束

1.1 您可以为自身定义最小和最大尺寸ConstraintLayout

  • android:minWidth 设置布局的最小宽度
  • android:minHeight 设置布局的最小高度
  • android:maxWidth 设置布局的最大宽度
  • android:maxHeight 设置布局的最大高度

1.2 控件尺寸约束
android:layout_width可以通过 3 种不同方式设置和 android:layout_height属性 来指定控件的尺寸:

  • 使用特定维度(文字值,例如123dp或Dimension引用)
  • 使用WRAP_CONTENT,这将要求小部件计算自己的大小
  • 使用0dp, 相当于 " MATCH_CONSTRAINT"

重要提示:
MATCH_PARENT不建议用于ConstraintLayout. 可以通过MATCH_CONSTRAINT将相应的左/右或上/下约束设置为来定义类似的行为"parent"。

WRAP_CONTENT (添加在 1 . 1中):强制约束
如果维度设置为WRAP_CONTENT,则在 1.1 之前的版本中,它们将被视为文字维度——也就是说,约束不会限制结果维度。虽然通常这已经足够(并且更快),但在某些情况下,您可能希望使用WRAP_CONTENT,但继续强制执行约束以限制结果维度。在这种情况下,您可以添加相应的属性之一:

  • app:layout_constrainedWidth="true|false"
  • app:layout_constrainedHeight="true|false"

MATCH_CONSTRAINT维度(添加在 1 . 1中)
当维度设置为MATCH_CONSTRAINT时,默认行为是让结果大小占用所有可用空间。有几个额外的修饰符可用:

layout_constraintWidth_min和layout_constraintHeight_min: 将设置此维度的最小尺寸
layout_constraintWidth_max和layout_constraintHeight_max: 将设置此维度的最大尺寸
layout_constraintWidth_percent和layout_constraintHeight_percent: 将此维度的大小设置为父维度的百分比

比率: 宽高比
您还可以将小部件的一个维度定义为另一个维度的比率。为此,您需要将至少一个约束维度设置为0dp(即MATCH_CONSTRAINT),并将属性设置layout_constraintDimensionRatio为给定的比率。例如:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <!--
    layout_constraintDimensionRatio(宽高比)
    如果想实现一个固定宽高比的顶部标题栏的话,可以将宽和高设置为 0dp,
    然后为其设置 app:layout_constraintDimensionRatio 属性,设定宽高比为16:7-->
    <TextView
        android:id="@+id/tv1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/colorAccent"
        app:layout_constraintDimensionRatio="h,16:8"
        android:gravity="center"
        android:text="@string/app_name"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <!--底部  app:layout_constraintDimensionRatio="w,1:3"-->
    <TextView
        android:id="@+id/tv2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/colorPrimary"
        app:layout_constraintDimensionRatio="w,1:3"
        android:gravity="center"
        android:text="stringapp_name"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        />


    <!--剩余布局居中-->
    <TextView
        android:layout_width="100dp"
        android:layout_height="0dp"
        android:gravity="center"
        android:text="@string/app_name"
        android:background="#ff0000"
        app:layout_constraintDimensionRatio="w,15:25"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv1"
        app:layout_constraintBottom_toTopOf="@+id/tv2"
        />

</android.support.constraint.ConstraintLayout>

除此之外,在设置宽高比的值的时候,还可以在前面加W或H,分别指定宽度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3"指的是 高:宽=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 宽:高=2:3

比率.png

...

7.Guideline(指导线):像辅助线一样,在预览的时候帮助你完成布局

Guildline的主要属性:

  • android:orientation 垂直vertical,水平horizontal
  • layout_constraintGuide_begin 开始位置
  • layout_constraintGuide_end 结束位置
  • layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)
    <android.support.constraint.Guideline
        android:id="@+id/guideline1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="50dp" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />
指导线.png

总结:

Constraint 约束布局为了解决嵌套布局的弊端,更快的加载页面而出现,但是约束布局需要整体架构页面要有明确的构建页面的思维,故而学习以及思维模式要有的.所以个人感觉是简单页面还是用相对布局,线性布局就够了,对于复杂布局约束布局是你优化页面加载的不二之选.
*写作不容易,且赞且珍惜!!!*

1.官方介绍

2.构建页面

3.源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容