ConstraintLayout约束布局Google推出来也有一年多时间了,从Android Studio2.2开始已经开始支持视图拖拽了,ios早就有这个功能,本来一直觉得这个布局就是RelativeLayout的拖拽版本,但是后来粗略的看了下这个布局一些特性,有很多新增属性以及很多扩展都跟RelativeLayout有着很大的不同,觉得还是很有必要学习一下的.
那 now 打开官方文档跟着我开始这个布局的学习之旅吧
可以看到这个列表提供了这么多约束属性,其实这些属性虽然看起来密密麻麻很复杂,但是我们只要拿它跟RelativeLayout对比有很多都是类似的,这里放张对比图
我们以官网介绍的其中一个属性为例
例如如果让Button B的左侧位于Button A的右侧就可以在Button B中去使用layout_constraintLeft_toRightOf这个属性指定id为Button A.
可以看到约束布局跟RelativeLayout不同的是,这些约束属性不仅可以指定要去约束的另一个控件的id,还可以直接填写parent跟这个控件当前的父布局进行约束,像上面的例子效果就像是二根橡皮绳用相同的力左右拉着同一个物体,只要控件大小不是跟父布局大小相同的话,那么它就被拉扯着居中在父布局中,这种属性很适合我们去做水平或者垂直居中的这样操作.
当然我们也可以使用Bias这个属性去指定拉扯力度的偏向, 如果想让这个控件稍微像左边偏移一些,就可以使用layout_constraintHorizontal_bias这个属性
比如上面我们水平Bias属性设置了0.3就表示控件左侧偏移父布局30%的距离,上述默认居中Bias默认偏向值是50%。垂直偏向是这个属性layout_constraintVertical_bias,原理相同。
Visibility behavior(可见行为)
在其他布局中比如RelativeLayout中假设我们指定Button B位于Button A的右侧,我们给Button A设置一个左边距margin_left =100dp,然后给Button B也设置一个左边距margin_left=20dp,当Button A被gone掉时,那么此时只有Button B显示,而此时Button B距离最左侧也就是父布局的margin_left等于20dp。这没毛病,在ConstraintLayout中这么做效果同样如此,But ! ConstraintLayout给我提供了一系列针对这种行为拓展的属性。
我们可以用这些属性去指定如果依赖的约束的控件gone掉后,距离它的margin是多少。
我们下面测试一下看下效果如何
<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/layout"
tools:context="com.zhuoyi.nestedscrollingdemo.MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="parent"
android:layout_marginLeft="50dp"
tools:text="button1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/button1"
android:layout_marginLeft="50dp"
tools:text="button2"/>
</android.support.constraint.ConstraintLayout>
简单弄了二个Button,界面效果如下所示
当我把Button1 gone后可以看到确实如上所示,就剩Button2显示了然后跟父布局左边距50dp,但是当我加上一个app:layout_goneMarginLeft="100dp"这个属性后可以看到Button1 gone掉后Button2距离父布局左侧边距变成了100dp.
我们通过上述属性去给控件指定一个最大或者最小的(宽度、高度),什么意思呢?如果我们给控件的(宽度、高度)设置一个WRAP_CONTENT,那么最大的(宽度、高度)就会使用我们指定的这个最大(宽度、高度)
看gif图。
<Button
android:maxWidth="100dp"
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="ButtonaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
tools:layout_editor_absoluteX="47dp"
tools:layout_editor_absoluteY="78dp"/>
在ConstraintLayout中子控件指定自己宽度有以下三种方式
The dimension of the widgets can be specified by setting the android:layout_width and android:layout_height attributes in 3 different ways:
Using a specific dimension (either a literal value such as 123dp or a Dimension reference)
Using WRAP_CONTENT, which will ask the widget to compute its own size
Using 0dp, which is the equivalent of "MATCH_CONSTRAINT"
a : 使用一个固定的dp大小
b: 使用WRAP_CONTENT,子控件将自己计算自己的大小
c: 使用"MATCH_CONSTRAINT"这个属性,这个属跟"MATCH_PARENT"类似但是它不是匹配父控件的尺寸而是匹配当前控件所在的约束的尺寸。
在ConstraintLayout中我们把控件大小设置为"WRAP_CONTENT"时,ConstraintLayout是不会界限我们控件的大小的,但是在一些情况下,我们可能想限时一下这个大小就可以使用这个属性,什么意思呢?
我们把Button2约束在Button1的左边然后把Button2宽度设置为“WRAP_CONTENT”然后文字加长很多可以看到效果图里Button2已经越界显示了
这时我们使用app:layout_constrainedWidth=”true”这个属性就可以把控件内容显示在这个约束里而不会超出父控件,但是记住这个属性是1.1版本后新添加的。
未完待续。。。。。