<TextView
android:layout_width="0dp"
android:layout_height="match\_parent"
android:gravity="center"
android:text="第二个文本框"
android:layout_weight="2"
android:background="#ff0000"/>
<TextView
android:layout_width="0dp"
android:layout_height="match\_parent"
android:gravity="center"
android:text="第三个文本框"
android:layout_weight="3"
android:background="#008000"/>
</LinearLayout>

#### 1.4、常见问题
(1)文字没有对齐如何解决?
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:background="#55ff0000"
android:gravity="center"
android:text="aaaaaaaaaaaaaaaa"/>
<TextView
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:background="#5500ff00"
android:gravity="center"
android:text="b"/>
<TextView
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:background="#550000ff"
android:gravity="center"
android:text="c"/>

很明显,第一个`textview`的对齐方式不是我们想要的,出现这种现象的原因是`LinearLayout默认子控件按照基准线对齐,所以我们需要在`LinearLayout`中添加一个属性就即可解决:android:baselineAligned=“false” 使得子控件不按照基线对齐。
(3)weightSum属性得使用
如果布局中只有一个控件,并且我只想让它占据1/2的宽度,这个时候就可以利用LinearLayout的weightSum属性,来看看这个例子:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:background="#55ff0000"
android:gravity="center"
android:text="aaaaaaaaaaaaaaaa"/>

### 2、相对布局 RelativeLayout
#### 2.1、定义
相对布局:相对布局也是常用的布局之一,它可以设置某一个控件相对于其他控件的位置,这些位置可以包括上下左右等,因此相较于其他的布局方式而言具有很大的灵活性。
1.核心属性图

2.父容器定位属性示意图

3.根据兄弟组件定位
恩,先说下什么是兄弟组件吧,所谓的兄弟组件就是处于同一层次容器的组件,如图

* `图中的组件1,2就是兄弟组件`了,而`组件3与组件1或组件2并不是兄弟组件`,所以组件3不能通过 组件1或2来进行定位,比如layout\_toleftof = "组件1"这样是会报错的!
切记! 关于这个兄弟组件定位的最经典例子就是"梅花布局"了,下面代码实现下:

<!-- 这个是在容器中央的 -->
<ImageView
android:id="@+id/img1"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:src="@drawable/pic1"/>
<!-- 在中间图片的左边 -->
<ImageView
android:id="@+id/img2"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_toLeftOf="@id/img1"
android:layout_centerVertical="true"
android:src="@drawable/pic2"/>
<!-- 在中间图片的右边 -->
<ImageView
android:id="@+id/img3"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_toRightOf="@id/img1"
android:layout_centerVertical="true"
android:src="@drawable/pic3"/>
<!-- 在中间图片的上面-->
<ImageView
android:id="@+id/img4"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_above="@id/img1"
android:layout_centerHorizontal="true"
android:src="@drawable/pic4"/>
<!-- 在中间图片的下面 -->
<ImageView
android:id="@+id/img5"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_below="@id/img1"
android:layout_centerHorizontal="true"
android:src="@drawable/pic5"/>
#### 2.2、属性说明
相对布局常用的属性:
第一类:属性值为true或false:相对于父元素的位置
android:layout_centerHrizontal 水平居中
android:layout_centerVertical 垂直居中
android:layout_centerInparent 相对于父元素完全居中
android:layout_alignParentBottom 贴紧父元素的下边缘
android:layout_alignParentLeft 贴紧父元素的左边缘
android:layout_alignParentRight 贴紧父元素的右边缘
android:layout_alignParentTop 贴紧父元素的上边缘
android:layout_alignWithParentIfMissing 如果对应的兄弟元素找不到的话就以父元素做参照物
实例:
<?xml version="1.0" encoding="utf-8"?>

第二类:属性值必须为id的引用名“@id/id-name”,
//相对于子元素外部的位置
android:layout_below 在某元素的下方
android:layout_above 在某元素的的上方
android:layout_toLeftOf 在某元素的左边
android:layout_toRightOf 在某元素的右边
//相对于子元素内部的位置
android:layout_alignTop 本元素的上边缘和某元素的的上边缘对齐
android:layout_alignLeft 本元素的左边缘和某元素的的左边缘对齐
android:layout_alignBottom 本元素的下边缘和某元素的的下边缘对齐
android:layout_alignRight 本元素的右边缘和某元素的的右边缘对齐
**实例:相对于元素外部四周**
<?xml version="1.0" encoding="utf-8"?>

**实例:相对于元素内部四周**
<?xml version="1.0" encoding="utf-8"?>

第三类:属性值为具体的像素值,如30dip,40px
android:layout_marginBottom 离某元素底边缘的距离
android:layout_marginLeft 离某元素左边缘的距离
android:layout_marginRight 离某元素右边缘的距离
android:layout_marginTop 离某元素上边缘的距离
android:gravity
* android:gravity属性是对该view 内容的限定.比如一个button 上面的text. 你可以设置该text 在view的靠左,靠右等位置.以button为例,android:gravity="right"则button上面的文字靠右
android:layout\_gravity
* android:layout\_gravity是用来设置该view相对与起父view 的位置.比如一个button在linearlayout里,你想把该button放在靠左、靠右等位置就可以通过该属性设置.以button为例,android:layout\_gravity="right"则button靠右
#### 2.3、padding与layout\_margin的区别与用法
Margin:设置组件与父容器(通常是布局)的边距
android:layout_margin: 指定控件的四周的外部留出一定的边距
android:layout_marginLeft: 指定控件的左边的外部留出一定的边距
android:layout_marginTop: 指定控件的上边的外部留出一定的边距
android:layout_marginRight: 指定控件的右边的外部留出一定的边距
android:layout_marginBottom: 指定控件的下边的外部留出一定的边距
Padding:设置组件内部元素间的边距(可以理解为填充)
android:padding :指定控件的四周的内部留出一定的边距
android:paddingLeft: 指定控件的左边的内部留出一定的边距
android:paddingTop: 指定控件的上边的内部留出一定的边距
android:paddingRight: 指定控件的右边的内部留出一定的边距
android:paddingBottom: 指定控件的下边的内部留出一定的边距
**android:layout\_margin就是设置view的上下左右边框的额外空间**
**android:padding是设置内容相对view的边框的距离**
* padding,含义为“填充”,像垫肩压类似的填充物,一个控件的padding及此控件内部的填充,由此可见padding是以所被定义的控件A为parent控件,而内部的内容物与控件A的间距。而layout\_margin是A控件所在的控件为parent控件,是A与其的间距。
* 其实概念很简单,padding是站在父view的角度描述问题,它规定它里面的内容必须与这个父view边界的距离。margin则是站在自己的角度描述问题,规定自己和其他(上下左右)的view之间的距离,如果同一级只有一个view,那么它的效果基本上就和padding一样了

当按钮分别设置以上两个属性时,得到的效果是不一样的。
android:paddingLeft=“30px”
按钮上设置的内容(例如图片)离按钮左边边界30个像素
android:layout_marginLeft=“30px”
整个按钮离左边设置的内容30个像素
使用示例
**1、两个都不加**
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="100dip"
android:layout_height="100dip"
android:background="#000000"
android:text="Hello" />

**2、只加padding**
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="100dip"
android:layout_height="100dip"
android:background="#000000"
android:text="Hello" />

**3、只加margin**
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="100dip"
android:layout_height="100dip"
android:background="#000000"
android:layout_margin="30dip"
android:text="Hello" />

注意说明
* 在LinearLayout、RelativeLayout、TableLayout中,这2个属性都是设置都是有效的
* 在FrameLayout中,android:layout\_margin是无效的,因为FrameLayout里面的元素都是从左上角开始绘制的
* 在AbsoluteLayout中,没有android:layout\_margin属性
在此提醒,xml参数中含有layout的参数项目为定义的控件相对于parent的关联,没有的一般为本身的定义,以上内容与此相符。又类似于gravity跟layout\_gravity,带layout的是相对于parent的大体位置,而不带的是自身内部内容的大体位置。
### 3、相对布局 ConstraintLayout
在以前,android是使用布局如LinearLayout 、RelativeLayout等来构建页面,但这些布局使用起来很麻烦,并且经常需要一层一层嵌套,写一个简单的页面就需要费很大的劲。
1、较高的性能优势。
* 布局嵌套层次越高,性能开销越大。而使用ConstraintLayout,经常就一层嵌套就搞定了,所以其性能要好很多。
* 详细的性能分析可参见:[解析ConstraintLayout的性能优势](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)
2、完美的屏幕适配
* ConstraintLayout的大小、距离都可以使用比例来设置,所以其适配性更好。
3、书写简单
4、可视化编辑。
* ConstraintLayout也有十分方便完善的可视化编辑器,不用写xml也基本上能实现大部分功能。但个人还是比较喜欢写xml,所以本篇文章主要介绍如何使用代码控制。如果想看如何使用可视化编辑器,可以参考郭霖大神的[这篇文章](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)
api ‘com.android.support.constraint:constraint-layout:1.1.2’
#### 3.1、app:layout\_constraint基础属性详解
| 属性 | 描述 |
| --- | --- |
| app:layout\_constraintLeft\_toLeftOf | 把A的left side放在B的left side(左边对齐) |
| app:layout\_constraintLeft\_toRightOf | 把A的left side放在B的right side(左边相对右边对齐) |
| app:layout\_constraintRight\_toLeftOf | 把A的right side放在B的left side(右边相对左边对齐) |
| app:layout\_constraintRight\_toRightOf | 把A的right side放在B的right side(右边对齐) |
| app:layout\_constraintTop\_toTopOf | 把A的top side放在B的top side(顶部对齐) |
| app:layout\_constraintTop\_toBottomOf | 把A的top side放在B的bottom side(顶部相对底部对齐) |
| app:layout\_constraintBottom\_toTopOf | 把A的bottom side放在B的top side(底部相对顶部对齐) |
| app:layout\_constraintBottom\_toBottomOf | 把A的bottom side放在B的bottom side(底部对齐) |
| app:layout\_constraintStart\_toEndOf | 把A的start position放在B的end position(起始位置相对结束位置对齐) |
| app:layout\_constraintStart\_toStartOf | 把A的start position放在B的start position(起始位置对齐) |
| app:layout\_constraintEnd\_toStartOf | 把A的end position放在B的start position(结束位置相对起始位置对齐) |
| app:layout\_constraintEnd\_toEndOf | 把A的end position放在B的end position(结束位置对齐) |
| app:layout\_constraintBaseline\_toBaselineOf | 把A的bottom side放在B的top side(基准线对齐) |
来看个例子:

<android.support.constraint.ConstraintLayout
…>
<Button
android:id="@+id/a"
....
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="A" />
<Button
android:id="@+id/b"
....
app:layout_constraintLeft_toRightOf="@id/a"
app:layout_constraintTop_toTopOf="@id/a"
android:text="B" />
<Button
android:id="@+id/c"
....
app:layout_constraintLeft_toLeftOf="@id/a"
app:layout_constraintTop_toBottomOf="@id/a"
android:text="C" />
<Button
android:id="@+id/d"
....
app:layout_constraintLeft_toRightOf="@id/a"
app:layout_constraintTop_toTopOf="@id/c"
android:text="D" />
</android.support.constraint.ConstraintLayout>
从中可以看到,
1、layout\_constraint\*属性的值可以是某个id或者parent(父布局)
2、B要位于A的右边,则使用app:layout\_constraintLeft\_toRightOf="@id/a",C位于A的下边,则使用app:layout\_constraintTop\_toBottomOf="@id/a"
对于一个View的边界界定,官方给了下面这张图:

#### 3.2、约束布局的margin控制
在约束布局中,margin控制需要存在约束关系的才会生效,比如控件A某条边相对于控件B的某条边存在约束关系,则控件A与B之间的margin才会生效。
<?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:id=“@+id/root”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>
<TextView
android:id="@+id/right_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/color_1"
android:gravity="center"
android:text="右上角"
app:layout_goneMarginStart="20dp"
android:layout_marginStart="20dp"
android:textSize="32sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="120dp" />
<TextView
android:id="@+id/where"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我在哪里"
app:layout_goneMarginEnd="20dp"
android:layout_marginEnd="20dp"
android:background="#ff0000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/right_top"/>
</androidx.constraintlayout.widget.ConstraintLayout>
这里使用了两种margin属性,一种就是app:layout\_goneMarginEnd,这个只在right\_top被gone的时候生效;一种就是android:layout\_marginEnd,任何时候都生效。
但是这里的margin需要生效,只有id为where的TextView被id为right\_top的TextView所约束,那么id为where的TextView的margin相对于id为right\_top的TextView的才生效。而id为right\_top的TextView并没有被id为where的TextView约束,所以id为right\_top的TextView的margin\_start其实看不到生效。这里其实可以认为right\_top的margin\_start生效了,只不过是相对于parent的左边,但是因为right\_top在parent的右上角,所以看不到这个margin效果
#### 3.3、关于view gone

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
…>
<Button
android:id="@+id/a"
...
android:layout_marginLeft="100dp"
android:layout_marginTop="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/b"
...
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
app:layout_constraintLeft_toRightOf="@id/a"
app:layout_constraintTop_toTopOf="@id/a"
/>
<Button
android:id="@+id/c"
....
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
app:layout_constraintLeft_toRightOf="@id/b"
app:layout_constraintTop_toTopOf="@id/b" />
</android.support.constraint.ConstraintLayout>
考虑一个问题,如果B动态设为gone了,C会怎么显示呢?
真实情况如下:

为什么会这样显示呢?看他的蓝图应该会好理解些:

可以看出,b设为gone之后,他的宽、高、margin都失效了,变为一个点了,但它的constrain还生效,位于指定的位置。c还是可以继续以他为锚点。
那么如何解决关于View gone引起的非预期的布局变化呢?
* 1、如果可以,尽量使用invisible
* 2、尽量其他view的布局不依赖会gone的view
* 3、google也提供了属性layout\_goneMargin\*=“xdp”,意思是比如当constrainleft的锚点gone时,layout\_goneMarginLeft将生效。但因为这个只能设置固定的距离,个人感觉灵活性不是很高。
#### 3.4、居中及bias
一个view如何设置为居中呢?如果查找属性,会发现并没有如RelativeLayout类似的layout\_centerVertical属性,那如何设置居中呢?constraint的思想很巧妙。
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”,则view会贴着父view的左边,设置app:layout\_constraintRight\_toRightOf=“parent” 则会贴着右边,那如果两个都设置,效果会怎样呢?

如图,两个都设置,view则会居中。
如果是在两个控件的中间,则可以:
<?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:id=“@+id/root”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>
<TextView
android:id="@+id/left_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/color_3"
android:gravity="center"
android:text="左上角"
android:textSize="32sp"
app:layout_constraintStart_toStartOf="@id/root"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="120dp" />
<TextView
android:id="@+id/right_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/color_1"
android:gravity="center"
android:text="右上角"
app:layout_goneMarginStart="20dp"
android:layout_marginStart="20dp"
android:textSize="32sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="120dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我在哪里"
android:background="#ff0000"
app:layout_constraintLeft_toRightOf="@+id/left_top"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/right_top"/>
</androidx.constraintlayout.widget.ConstraintLayout>

至此可以看出,对constraint的理解其实可以看成是像两个弹簧一样,如果只在左边加一个弹簧,右边没有,那左边的势必会把view拉到左边去,如果在右边也加一根弹簧,两个弹簧力相互平衡,则view就居中了。
上面是view居中,如果我想让view向左偏一些,或者位于1/3处该怎么处理?其实也是一样的,想象一下,如果左边的弹簧力大一些,view不是就自然往左偏了嘛。如何使力大一些呢?使用如下属性
* layout\_constraintHorizontal\_bias
* layout\_constraintVertical\_bias
这两个属性单独使用并不能生效,水平方向的必须要给控件的左右两边都添加约束才会生效,垂直方向的必须要给控件的上下两边都添加约束才可以生效。
bias即偏移量,他们的取值范围从0~1,0即挨着左边,1是挨着右边,所以要使处于1/3处,可以设置如下属性app:layout\_constraintHorizontal\_bias=“0.33”,效果图如下:

实例:
<?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:id=“@+id/root”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>
<Button
android:id="@+id/button13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintVertical_bias="0"
app:layout_constraintLeft_toRightOf="@+id/left_top"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteX="120dp"
tools:layout_editor_absoluteY="189dp" />
<TextView
android:id="@+id/left_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/color_3"
android:gravity="center"
android:text="左上角"
android:textSize="32sp"
app:layout_constraintStart_toStartOf="@id/root"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="120dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
比如这个例子,Button的左边被TextView的右边约束,Button的右边被parent约束,这样Button的左右两边都有约束,那么给Button添加水平方向的bias属性就可以生效,即根据Button的左边约束偏移一定的比例,这里就是相对于TextView的右边位置偏移40%。
bias的偏移,是根据控件的水平或者垂直方向的剩余位置的百分比来偏移。
#### 3.5、view的尺寸
设置view的大小除了传统的wrap\_content、指定尺寸、match\_parent(虽然官方不推荐使用match\_parent)外,还可以设置为0dp(官方取名叫MATCH\_CONSTRAINT),0dp在constraint可不是指大小是0dp,而是有特殊含义的。他的作用会随着不同的设置有不同的含义:
layout\_constraintWidth\_default,有三个取值,作用如下:
* 1、spread,默认值,意思是占用所有的符合约束的空间
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
…>
<Button
android:id="@+id/a"
android:layout_width="0dp"
...
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
</android.support.constraint.ConstraintLayout>

可以看到layout\_width为0dp,实际的效果则是宽度和约束一样,左右两边的留白是margin的效果。
2、percent,意思是按照父布局的百分比设置,需要layout\_constraintWidth\_percent设置百分比例
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout >
<android.support.constraint.ConstraintLayout
android:layout_width="300dp"
android:layout_height="400dp"
app:layout_constraintHorizontal_bias="0.3"
>
<Button
android:id="@+id/a"
android:layout_width="0dp"
...
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.4" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

A的宽度设为0.4,则其宽度为父布局的0.4倍。另外,设置了layout\_constraintWidth\_percent属性,可以不用指定layout\_constraintWidth\_default,他会自动设置为percent
3、wrap,意思匹配内容大小但不超过约束限制,注意和直接指定宽度为wrap\_content的区别就是不超过约束限制,如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
…>
<Button
android:id="@+id/a"
...
app:layout_constraintLeft_toLeftOf="parent" />
<Button
android:id="@+id/c"
...
app:layout_constraintRight_toRightOf="parent" />
<Button
android:id="@+id/b"
android:layout_width="0dp"
...
app:layout_constraintWidth_default="wrap"
app:layout_constraintLeft_toRightOf="@id/a"
app:layout_constraintRight_toLeftOf="@id/c"/>
<Button
android:id="@+id/d"
android:layout_width="wrap_content"
...
app:layout_constraintTop_toBottomOf="@id/b"
app:layout_constraintLeft_toRightOf="@id/a"
app:layout_constraintRight_toLeftOf="@id/c"/>
</android.support.constraint.ConstraintLayout>

可以看到虽然文字很长,但第一行的绿色button宽度达到约束时,就不在增加,而第二行的button显示了完整的内容,超过约束的限制。
ratio
layout\_constraintDimensionRatio,即宽和高成一定的比例,其值可以是"width:height"的形式,也可以是width/height的值。该属性生效的前提:宽和高其中有一项为0dp,有constraint。下面按照有几个0dp来分别介绍下:
* 如果只有一项为0dp,则该项值按照比例计算出来。比如高为20dp,宽为0dp,radio为"2:1",则最终宽为40dp
* 如果两项都为0dp,则尺寸会设置为满足约束的最大值并保持比例。因为这是系统计算的,有的时候不是我们想要的,我们也可以通过在前面加H、W来指定是哪一个边需要计算。例如"H,2:1",则是指宽度匹配约束,高度是宽度的1/2
max min
有如下属性可以设置其的最大最小值,含义如字面值一样:
layout_constraintWidth_min
layout_constraintWidth_max
layout_constraintHeight_max
layout_constraintHeight_min
在ConstraintLayout中给控件设置min的宽度和高度,必须是要控件的layout\_width或者layout\_height为wrap\_content或者0dp时。给控件设置max的宽度或者高度的时候,必须是要控件的layout\_width或者layout\_height为0dp时。
不过在设置max的时候需要注意一点,如果单纯只是设置了0dp,如果没给控件添加对应的左右约束或者上下约束,比如没有设置左右约束,那么layout\_constraintWidth\_max设置的再大也不会超过整个控件的wrap\_content的长度。

这里的绿色区域的控件,宽度显示的明显没有达到550dp,但是也不会继续变长了。
如果是设置了左右约束,那么最大宽度的限制也就是左右两个约束中间的剩余空间宽度

#### 3.6、Guideline和Barrier
1. GuideLine
即参考线的意思,有水平参考线和竖直参考线两种。他的作用就像是一个虚拟的参考线,只是用来方便其他View以他为锚点来布局。
如上一篇所了解到的,ConstraintLayout 的定位原则就是一个View参考其他View的相对布局,如果有的时候当前布局没有合适的参考View,而建一个专门用于定位的View又会太重,这种情况正是GuideLine的用武之地。
例如:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
…>
<android.support.constraint.Guideline
android:id="@+id/guideline"
...
android:orientation="vertical"
app:layout_constraintGuide_percent="0.33" />
<android.support.constraint.Guideline
android:id="@+id/guideline2"
...
android:orientation="horizontal"
app:layout_constraintGuide_begin="130dp" />
<Button
...
app:layout_constraintLeft_toLeftOf="@id/guideline"
app:layout_constraintTop_toTopOf="@id/guideline2" />
</android.support.constraint.ConstraintLayout>

可以看到我分别添加了一个水平参考线和竖直参考线,之后的Button的布局就参考与这两个参考线,而在布局中并不会显示。
Guideline的大部分的属性如layout\_width都是不会生效的,而他的位置的确定是由下面三个属性之一来确定的:
* layout\_constraintGuide\_begin:距离父布局的左边或者上边多大距离
* layout\_constraintGuide\_end:距离父布局的右边或者下边多大距离
* layout\_constraintGuide\_percent:百分比,0~1,距离父布局的左边或者上边占父布局的比例
2. Barrier
屏障,一个虚拟View。他主要解决下面遇到的问题:

如上图布局,两个TextView,一个button位于他们的右边。现在button设置的是在下面TextView的右边。假设有时候上面的TextView文本变长了,则布局会变为下面这个样子:

上面的TextView和Button重叠了。这时该怎么解决这个问题呢?Button只能设置一个View作为锚点,设置了上面就顾不了下面了。。。
所以就诞生了Barrier,他可以设置N个View作为锚点,使用方式如下:
<android.support.constraint.Barrier
android:id=“@+id/barrier”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
app:barrierDirection=“end”//end,left,right,top,bottom
app:constraint_referenced_ids=“text1,text2” />
则Barrier始终位于text1,text2两个View最大宽度的右边,示意图如下:

3.Guideline和Barrier的区别
这两个都是线条,都是辅助约束的,但是这两个有一点区别,就是当控件比如出现切换手机语言,而造成控件上的文本显示长度出现变化的时候,Guideline并不会随着控件的长度变化而变化,这样就会造成约束不灵活,而Barrier可以根据控件的宽高变化,灵活移动位置。
所以控件宽高是随着内容动态变化的,建议使用Barrier,如果控件的内容是不变的,可以使用Guideline。