ConstraintLayout 属性详解 和Chain的使用

  • Post author:
  • Post category:其他


想看我更多文章:

【张旭童的博客】


blog.csdn.net/zxt0601


想来gayhub和我gaygayup:

【mcxtzhang的Github主页】


github.com/mcxtzhang

概述

小伙伴们好久不见,我又回来啦。

说实话这篇文章写的算是比较晚了,距离

ConstraintLayout

出现至今已经有一年了。

且自AS2.3起创建新的

Activity

,默认的layout根布局就是

ConstraintLayout



所以再不学习就真的晚了。

我也是正式开始学习的道路,先说一下我的学习过程:

  • 先阅读了

    ConstraintLayout官方文档



    Guideline官方文档
  • 实践每个属性并记下笔记(翻译)
  • 学习了郭神关于

    ConstraintLayout


    可视化操作

    (拖拖拽拽)的博客,发现博客中对

    Chain

    的概念没有提及
  • 查询关于

    Chain

    以及一些疑点的资料
  • 整理成文
  • 当然中间也遇到了许许多多的问题

本文的顺序,大体按照

ConstraintLayout官方文档

的顺序依次讲解(翻译)属性和用法,并

对疑难点进行额外说明。


关于

可视化操作

,可参考我写的

动态图解&实例 ConstraintLayout Chain

和郭神博文

可视化操作

使用前的准备


引入也有坑

,无力吐槽。

先放上 截止至20170524,

最新版本1.0.1


compile 'com.android.support.constraint:constraint-layout:1.0.1'

坑是啥?因为我使用的是最新的release版AndroidStudio2.3.2,新建Activity后,自动帮我引入的是

1.0.8-alpha

版本,

开始我就这么愉快的学习了,可是当我学习到

Chain

相关姿势时,特码的,他居然报错。说找不到属性:

Error:(10) No resource identifier found for attribute ‘layout_constraintHorizontal_chainStyle’ in package ‘com.mcxtzhang.constraintlayoutdemo’

ok,那我百度,显然搜不到的,ok,那我再google,特么的居然也搜不到。

震惊,于是机智的我去看源码,

发现我使用的

1.0.8-alpha

版本的源码里根本没有

Chain

相关属性的支持

,所以我就觉得一定是引入的版本有问题,于是我用google搜索”ConstraintLayout last version”,发现诶~官方有说最新版链接如下:


tools.android.com/recent/cons…


按照这个链接提示,

最新版是

1.0.2

,嗯哼,当我换成

1.0.2

后,发现无法download….


不知道是网络问题还是什么问题,提示我无法下载,具体的错误记不清了。反正就是无法获取到这个版本。

特么的机智的我又直接去AndroidStudio的

Library Dependency

里去搜索,发现居然

搜不到

“ConstraintLayout “的库。再次懵逼。

后来我进行最后的一次尝试,因为我看google官方上1.0.2版本的上一个版本是1.0.1.于是我修改版本号,sync gradle,居然成功了。

总结踩坑历程:

  • 1 最新Release版AndroidStudio模板自带的是1.0.8alpha版ConstraintLayout
  • 2 使用

    Chain

    相关属性报错
  • 3 发现该版本源码没有

    Chain

    相关属性
  • 4 官网说的最新版1.0.2 我无法下载
  • 5 AndroidStudio自带的

    Library Dependency

    搜不到

    ConstraintLayout
  • 6 修改版本号为1.0.1 下载

对此,我只能说“惊不惊喜! 意不意外!”

ConstraintLayout是什么

先概况一下,它是一个

为了解决布局嵌套和模仿前端flexible布局的一个新布局。

从字面上理解,

ConstraintLayout



约束布局



在我理解,这是一个

RelativeLayout

的升级版。

而当初推出

RelativeLayout

的目的是为了在

减少多层嵌套布局



推出

ConstraintLayout

也是同样的目的,

尽可能的使布局 宽而短,而不是 窄而长。




ConstraintLayout

更加强大,很多需要多层嵌套的布局,使用

ConstraintLayout

只需要一层即可解决。

它的

Chain

几种style方式,和前端的flexbox布局风格一致,官方文档中也说了它是flexible方式布局控件的东西。

A ConstraintLayout is a ViewGroup which allows you to position and size widgets in a flexible way.

而且搭配可视化的操作,使得布局也变得更轻松。

Google官方推荐所有操作都在”Design”区域搞定,即通过可视化拖拖拽拽生成布局大致的样子,然后针对具体属性、约束 精细修改。

甚至可以这么说,你完全不需要知道

ConstraintLayout

的具体属性值分别是什么,只通过拖拽和鼠标点击就可以实现一些布局。

那么本文的意义何在呢?

我觉得首先是要知其然知其所以然,那些拖拽点击生成的代码属性到底是什么意思?通过本文可以了解。

另外 虽然大部分操作可以在“Design”区域完成,但是保不齐的需要你切换至“Text”区域,写上一两行属性代码,了解 这些属性 总是有益无害的。

而且,有一些属性是无法简单通过拖拽点击完成的,例如

Margins when connected to a GONE widget

刚才提到

RelativeLayout

,其实

RelativeLayout

也是通过约束来布局子View的呀,

以前

RelativeLayout

的约束有两种:

  • 1

    子控件和子控件之间的约束

    (如

    android:layout_below="@id/title"

  • 2

    子控件和父控件的约束

    (如

    android:layout_alignParentTop="true"

现在

ConstraintLayout

也是类似的,只不过除了以上两种约束,还多了一种

  • 3

    子控件和

    Guideline

    的约束

其实关于和

Guideline

的约束,也可以理解成约束1,因为

Guideline

其实就是一个在屏幕上不显示的View罢了。稍后讲到

Guideline

会带大家看看它巨简单的源码。

下面开始正文,开始属性的讲解

相对定位 (Relative positioning)

这一节的属性和相对布局的很像,

值得注意的是参数取值是

ID(

@id/button1

)代表约束1、3, 或者 字符串

"parent"

代表约束2:


  • 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

属性都形如

layout_constraintXXX_toYYYOf

,

这里我的理解,

constraintXXX

里的

XXX

代表是这个子控件

自身的哪条边

(

Left、Right、Top、Bottom、Baseline

),



toYYYOf

里的

YYY

代表的是和

约束控件



哪条边


发生约束

(取值同样是

Left、Right、Top、Bottom、Baseline

)。



XXX



YYY


相反时

,表示控件自身的

XXX

在约束控件的

YYY

的一侧,

例如

app:layout_constraintLeft_toRightOf="@id/button1"

,表示的是控件自身的左侧在button1的右侧。



XXX



YYY


相同时

,表示控件自身的

XXX

和约束控件的

YYY

的一侧

对齐



例如:

app:layout_constraintBottom_toBottomOf="parent"

,表示控件自身底端和父控件底端对齐。

代码为:

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Demo"/>
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button2"
        app:layout_constraintLeft_toRightOf="@id/button1"/>
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:text="button3 跳转match页"
        app:layout_constraintBottom_toBottomOf="parent"/>复制代码

图示:

Margins

margin和以往的使用一致,注意margin

不能为负值

即可。

在上图中也顺便展示了margin的使用。

当约束的widget为GONE时的Margins

Margins when connected to a GONE widget

举例,当A控件 约束 在B控件的左边,B控件GONE了,

此时A会额外拥有一个margin的能力,来“补充”B消失的导致的“位移”。


这就是本节的属性。

这一节的属性开始我并没有理解,后来是通过写了一些Demo实验才明白。奈何官方文档惜字如金,只有一句话,并没有Demo展示:

When a position constraint target’s visibility is View.GONE, you can also indicates a different margin value to be used using the following attributes:

先看属性:

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

在看Demo:

    <Button
        android:id="@+id/button4"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="button4"
        app:layout_constraintRight_toRightOf="parent"
        />

    <!-- android:layout_marginRight="10dp" 
    配合 app:layout_goneMarginRight="110dp"一起使用,
    在约束的布局gone时,起用goneMargin,
    但是一定要预先设置对应方向上的margin -->
    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="button5"
        app:layout_constraintRight_toLeftOf="@id/button4"
        app:layout_goneMarginRight="110dp"/>复制代码

此时图示:

当给button4 隐藏GONE掉以后:

图示:


会发现Button5纹丝不动,并没有收到Button4消失的影响。


这里我们再仔细看看button4的

android:layout_width="100dp"



而button5的

android:layout_marginRight="10dp"

,

app:layout_goneMarginRight="110dp"


110 = 100 +10 , 这是一道小学计算题。

什么意思?

几个注意事项:


  • app:layout_goneMarginRight

    要配合

    android:layout_marginRight

    一起使用。
  • 如果只设置了

    app:layout_goneMarginRight

    没有设置

    android:layout_marginRight

    ,则无效。(alpha版本的bug,1.0.1版本已经修复)
  • 在约束的布局gone时,控件自身的

    marginXXX

    会被

    goneMarginXXX

    替换掉,以本文Demo为例,原本button4宽度是100,button5的

    marginRight

    是10, 加起来是110,如果想让button4隐藏之后,button5仍然纹丝不动,则需要设置

    goneMarginRight

    为10+100 = 110.

居中定位和倾向(Centering positioning and bias)

居中定位

约束布局一个有用的地方是它如何处理“不可能”的约束。

比如你定义如下:

<android.support.constraint.ConstraintLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>复制代码

按照我们第一小节讲的属性值,这个定义的意思是,Button的左边和父控件的左边对齐,Button的右边和父控件的右边对齐。

可是控件是

wrap_content

的,它如果不铺满父控件要如何能满足这两个约束呢?

实际效果如下:

控件会

居中显示

,因为这两个约束作用 类似于 水平方向上,有相反的力 去拉控件,最终控件会居中显示。

倾向(Bias)

搭配bias,能使约束偏向某一边,

默认是0.5

,有以下属性:

  • layout_constraintHorizontal_bias (0最左边 1最右边)
  • layout_constraintVertical_bias (0最上边 1 最底边)

比如上个Demo,我加入

app:layout_constraintHorizontal_bias="0.9"

,则会在水平方向上向右偏移至90%。

<android.support.constraint.ConstraintLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        ...
        app:layout_constraintHorizontal_bias="0.9"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>复制代码

对可见性的处理(Visibility behavior)

这一节是对前一节

goneMargin

的补充。

重点是Gone隐藏掉的控件,

会被解析成一个点,并忽略margin。


ConstraintLayout

能为

View.Gone



View

特殊处理。

通常,GONE的控件不会被显示,并且不是布局本身的一部分(即如果标记为GONE,则其实际尺寸并不会更改)。

但是在布局计算方面,GONE的View仍然是其中的一个重要区别:

对于布局传递,它们的维度将被视为零(基本上它们将被

解析为一个点



如果他们对其他小部件

有约束力

,那么他们仍然会受到尊重,

但任何margin都将等于零


注意A的margin也被忽略了。

拿上个Demo改一下,为A 加上一个

android:layout_marginRight="10dp"



为了使A 隐藏后,B仍能纹丝不动,则B的

app:layout_goneMarginRight="120dp"



B goneMarginRight120 = A宽度100 + A marginRight10 +B marginRight10

    <Button
        android:id="@+id/button4"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="button4"
        app:layout_constraintRight_toRightOf="parent"
        />
    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="button5"
        app:layout_constraintRight_toLeftOf="@id/button4"
        app:layout_goneMarginRight="120dp"/>复制代码

尺寸约束(Dimensions constraints)

ConstraintLayout的最小尺寸 (Minimum dimensions on ConstraintLayout)

可以为

ConstraintLayout

自身定义最小的尺寸,他会在

ConstraintLayout



WRAP_CONTENT

时起作用。

● android:minWidth

● android:minHeight

控件尺寸约束(Widgets dimension constraints)

控件的宽高有三种方式为其设置:

  • 确定尺寸

  • WRAP_CONTENT

  • 0dp

    ,就等于

    MATCH_CONSTRAINT

有些人可能有疑问,为什么不用

MATCH_PARENT

了。

官方文档如是说:

MATCH_PARENT is not supported for widgets contained in a ConstraintLayout, though similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to “parent”.

意思是

MATCH_PARENT

不再被支持了,通过

MATCH_CONSTRAINT

替代。

我们写个Demo看一下三种方式设置的效果吧:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/button10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="@+id/button"
        app:layout_constraintRight_toRightOf="@+id/button"
        app:layout_constraintTop_toBottomOf="@+id/button"/>

    <Button
        android:id="@+id/button11"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="@+id/button10"
        app:layout_constraintRight_toRightOf="@+id/button10"
        app:layout_constraintTop_toBottomOf="@+id/button10"/>

</android.support.constraint.ConstraintLayout>复制代码

效果如图:

有些人是不是要说,你特么逗我,不是说好的0dp等于

MATCH_CONSTRAINT

,应该是撑满屏幕的呀,

OK ,把刀放下。让我们仔细看这个

MATCH_CONSTRAINT

属性。它match的是约束。

而这里第三个按钮的约束是第二个按钮,所以它的宽度设置为

MATCH_CONSTRAINT

时,

是和它的约束按钮,即第二个按钮一样宽。



注意,此时,竖直方向上没有约束,所以不能使用

MATCH_CONSTRAINT

属性.

我们仅仅将第三个按钮的属性修改为

        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"复制代码

则它宽度会撑满屏幕:

我们再修改Demo,分别为后两个按钮加上margin:

<android.support.constraint.ConstraintLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/button10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="@+id/button"
        app:layout_constraintRight_toRightOf="@+id/button"
        app:layout_constraintTop_toBottomOf="@+id/button"/>


    <Button
        android:id="@+id/button12"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        app:layout_constraintLeft_toLeftOf="@id/button10"
        app:layout_constraintRight_toRightOf="@id/button10"
        app:layout_constraintTop_toBottomOf="@id/button10"/>

    <Button
        android:id="@+id/button11"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button12"/>

</android.support.constraint.ConstraintLayout>复制代码

效果如图:

最后,记住一句话

约束要和 0dp 的 方向一致。否则无效

比例(Ratio)

只有一个方向约束:

可以

以比例去定义View的宽高



为了做到这一点,需要将至少一个约束维度设置为

0dp

(即

MATCH_CONSTRAINT



并将属性

layout_constraintDimentionRatio

设置为给定的比例。

例如:

    <Button
        android:layout_width="200dp"
        android:layout_height="0dp"
        android:text="Ratio"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintTop_toTopOf="parent"/>复制代码

如图:

比例值有两种取值:

  • 浮点值,表示宽度和高度之间的比率 (2,0.5)
  • “width:height”形式的比例 (5:1,1:5)

当约束多于一个(宽高都被约束了)

如果两个维度均设置为MATCH_CONSTRAINT(0dp),也可以使用比例。 在这种情况下,系统会使用满足所有约束条件和比率的

最大尺寸



如果需要根据一个维度的尺寸去约束另一个维度的尺寸。

则可以在比率值的前面

添加 W 或者 H 来分别约束宽度或者高度

例如,如果一个尺寸被两个目标约束(比如宽度为0,在父容器中居中),可以使用 W 或H 来指定哪个维度被约束。

    <Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,2:1"
        app:layout_constraintTop_toTopOf="parent"/>复制代码

这里用“H”表示

以高度为约束

,高度的

最大尺寸

就是父控件的高度,“2:1”表示高:宽 = 2 : 1.

则宽度为高度的一半:

链条(Chains)

链条在同一个轴上(水平或者垂直)提供一个类似群组的统一表现。另一个轴可以单独控制。

创建链条(Creating a chain)

如果一组小部件通过双向连接(见图,显示最小的链,带有两个小部件),则将其视为链条。

链条头(Chain heads)

链条由在链的第一个元素(链的“头”)上设置的属性控制:

头是水平链最左边的View,或垂直链最顶端的View。

链的margin(Margins in chains)

如果在连接上指定了边距,则将被考虑在内。

例如

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/buttonB"/>

    <Button
        android:id="@+id/buttonB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toRightOf="@+id/buttonA"
        app:layout_constraintRight_toRightOf="parent"/>复制代码

通过

app:layout_constraintRight_toLeftOf="@+id/buttonB"



app:layout_constraintLeft_toRightOf="@+id/buttonA"

就建立了链条,(我中有你,你中有我)。

然后它们两个成了一个整体,所以链条左边设置

app:layout_constraintLeft_toLeftOf="parent"

使得和父控件左对齐,

右边设置

app:layout_constraintRight_toRightOf="parent"

使得和父控件右对齐,

这样整个链条就居中了,最后对左控件设置了margin,相当于整个链条左边有了margin

效果:

链条样式(Chain Style)

当在链的第一个元素上设置属性

layout_constraintHorizontal_chainStyle



layout_constraintVertical_chainStyle

时,链的行为将根据指定的样式(默认为

CHAIN_SPREAD

)而更改。

看图这里就很像JS里的flexible有木有。因为

ConstraintLayout

就是模仿flexible做的。

取值如下:


  • spread

    – 元素将被展开(默认样式)
  • 加权链 – 在spread模式下,如果某些小部件设置

    为MATCH_CONSTRAINT

    ,则它们将拆分可用空间

  • spread_inside

    – 类似,但链的端点将不会扩展

  • packed

    – 链的元素将被打包在一起。 孩子的水平或垂直偏差属性将影响包装元素的定位

拿加权链举个例子:

    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:text="Button"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/buttonB"/>

    <Button
        android:id="@+id/buttonB"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toRightOf="@+id/buttonA"
        app:layout_constraintRight_toRightOf="parent"/>复制代码

加权链(Weighted chains)




LinearLayou

t的

weight

类似。

链的

默认行为

是在

可用

空间中

平均分配元素

。 如果一个或多个元素使用

MATCH_CONSTRAINT

,它们将使用剩余的空白空间(在它们之间相等)。 属性

layout_constraintHorizontal_weight



layout_constraintVertical_weight

将决定这些都设置了

MATCH_CONSTRAINT

的View如何分配空间。 例如,在包含使用

MATCH_CONSTRAINT

的两个元素的链上,第一个元素使用权重为2,第二个元素的权重为1,第一个元素占用的空间将是第二个元素的两倍

最后关于链条,再给大家看一个关于

margin

的demo:

    <Button
        android:id="@+id/buttonA"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:text="Button"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/buttonB"/>

    <Button
        android:id="@+id/buttonB"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toRightOf="@+id/buttonA"
        app:layout_constraintRight_toRightOf="parent"/>复制代码

一图胜千言,可以看到虽然他们的weight相等,但是margin是被计算在约束里的,所以左边的按钮宽度比右边的小。


Guideline


Guideline

只能用于

ConstraintLayout

中,是一个工具类,

不会被显示,仅仅用于辅助布局



它可以是

horizontal

或者

vertical

的。(例如:

android:orientation="vertical"


  • vertical



    Guideline

    宽度为零,高度为

    ConstraintLayout

    的高度

  • horizontal



    Guideline

    高度为零,宽度为

    ConstraintLayout

    的高度

定位

Guideline

有三种方式:

  • 指定

    距离左侧或顶部

    的固定距离(

    layout_constraintGuide_begin

  • 指定

    距离右侧或底部

    的固定距离(

    layout_constraintGuide_end

  • 指定

    在父控件中

    的宽度或高度的

    百分比



    layout_constraintGuide_percent

一个栗子一看便知:

<android.support.constraint.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">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="100dp"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>复制代码

预览:

Guideline源码:

public class Guideline extends View {
    public Guideline(Context context) {
        super(context);
        super.setVisibility(8);
    }
    public Guideline(Context context, AttributeSet attrs) {
        super(context, attrs);
        super.setVisibility(8);
    }
    public Guideline(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        super.setVisibility(8);
    }
    public Guideline(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr);
        super.setVisibility(8);
    }
    public void setVisibility(int visibility) {
    }
    public void draw(Canvas canvas) {
    }
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        this.setMeasuredDimension(0, 0);
    }
}复制代码
public static final int GONE = 0x00000008;复制代码

源码就这么点,这货的源码和

ViewStub

有点像啊,可以看出

  • 它默认是GONE的。8 就是View.GONE的值。
  • 它的

    public void setVisibility(int visibility)

    方法被空实现了,所以用户也没办法改变它的可见度。
  • 推导出它一定是GONE的。在屏幕上不可见

  • this.setMeasuredDimension(0, 0);



    public void draw(Canvas canvas)

    的空实现,表明这是一个超轻量的View,不可见,没有宽高,也不绘制任何东西。仅仅作为我们的锚点使用。

总结

很久不写博客了,一是工作太忙了,二也是随意的写怕误人子弟。

这篇文章我写了整整一天,每个例子我都边写边跑了一遍,

也看了几篇别人的文章,有些人简单的翻译了官方文档,但是对文档中一些没有举例, 不那么好理解的地方也没有说明,于是便有了此文。

关于可视化操作,建议直接看我写的

动态图解&实例 ConstraintLayout Chain

和郭神博文

可视化操作



我觉得ConstraintLayout ,有这几篇就够了。

文中代码地址在我的Demo合集中:


github.com/mcxtzhang/D…

想看我更多文章:

【张旭童的博客】


blog.csdn.net/zxt0601


想来gayhub和我gaygayup:

【mcxtzhang的Github主页】


github.com/mcxtzhang