Bootstrap

ConstraintLayout 属性说明

以前在刚培训的时候提到的常用布局方式有 LinearLayout(线性布局)、RelativeLayout(相对布局)、 FrameLayout(帧布局)、TableLayou(表格布局)、AbsoluteLayout(绝对布局)、GridLayout(网格布局)。面试中一些过期题目常会问到常用的五种布局也就是刚才的前五个,而我们在开发中使用频率最高的也还是线性布局和相对布局,我以前的使用经验是布局不太复杂则用线性布局,复杂则用相对布局,这两种布局基本上就能满足我们大部分开发需求了。而在 Android Studio 2.2 后有一个新特性就是 ConstraintLayout(约束布局),现在的 Android Studio 新建工程的话默认使用的也是这个 ConstraintLayout,虽然已经出现了很久,但是由于之前项目没有要求,也就没过多了解这个布局的特性,但是早晚都会学的,所以在现在 ConstraintLayout 很完善的情况下,我也记录下它的各个属性的用法。

1 简介

ConstraintLayout,约束布局,感觉上是有点像取代 RelativeLayout 的,也是比较适用在布局多层嵌套的情况下的,但是它远比 RelativeLayout 要强大。网上有的小伙伴说它跟iOS 的 AutoLayout 有点像,我倒不会写 iOS,所以也没法比较。Android Studio 都有布局预览功能,即可视化,在这个可视化的界面上,我们是可以对控件进行拖拽的,但是之前的布局方式,相信开发者都不愿意拖拽而是用 XML 代码进行布局。而 ConstrainiLayout 却非常适合可视化编写布局,使用拖拽来进行控件的约束,然后 Android Studio 会自动生成 XML 代码。

 

2 属性说明

2.1 Relative Position

这部分的属性有点类似于 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_toStartOf:该控件的开始部分相对于某控件或父布局的开始部分对齐。
layout_constraintStart_toEndOf:该控件的开始部分相对于某控件或父布局的结束部分对齐。
layout_constraintEnd_toStartOf:该控件的结束部分相对于某控件或父布局的开始部分对齐。
layout_constraintEnd_toEndOf:该控件的结束部分相对于某控件或父布局的结束部分对齐。

 

其实看一下说明就知道这些属性怎么用了,形象一点说明,举一个小例子:

<?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"
    tools:context="com.qinshou.constraintlayoutdemo.MainActivity">

    <Button
        android:id="@+id/btn_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2"
        app:layout_constraintBottom_toTopOf="@+id/btn_1"
        app:layout_constraintLeft_toLeftOf="@id/btn_1"
        app:layout_constraintRight_toRightOf="@id/btn_1" />

    <Button
        android:id="@+id/btn_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button3"
        app:layout_constraintLeft_toLeftOf="@id/btn_1"
        app:layout_constraintRight_toRightOf="@id/btn_1"
        app:layout_constraintTop_toBottomOf="@+id/btn_1" />

    <Button
        android:id="@+id/btn_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button4"
        app:layout_constraintBottom_toBottomOf="@id/btn_1"
        app:layout_constraintRight_toLeftOf="@id/btn_1"
        app:layout_constraintTop_toTopOf="@+id/btn_1" />

    <Button
        android:id="@+id/btn_5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button5"
        app:layout_constraintBaseline_toBaselineOf="@id/btn_1"
        app:layout_constraintLeft_toRightOf="@id/btn_1" />
</android.support.constraint.ConstraintLayout>


预览出来的效果是这样的:

 

上面提到 ConstraintLayout 是非常适合拖拽来进行控件的约束的,至于怎么拖拽我不会截屏电脑动图,郭神的博文写得很详细,放一个传送门:

郭霖的专栏:Android新特性介绍,ConstraintLayout完全解析

 

2.2 Margins

android:layout_marginStart:设置控件距离开头view的边距。
android:layout_marginEnd:设置控件距离结尾view的边距。
android:layout_marginLeft:设置控件距离左边view的边距。

android:layout_marginRight:设置控件距离右边view的边距。
android:layout_marginTop:设置控件距离顶边view的边距。
android:layout_marginBottom:设置控件距离底边view的边距。

 

Margin属性的用法和之前的一样,不多赘述。

 

2.3 Margins when connected to a GONE widget

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

 

这些属性也是设置边距的,根据官方的解释是当某个位置的控件为 GONE 的时候,你也可以指定一个另外的边距。具体怎么用,举一个例子说明:

在一个 ConstrainLayout 上放两个按钮,设置 Button2 的左边距为 20dp:

<?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"
    tools:context="com.qinshou.constraintlayoutdemo.MainActivity">

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

    <Button
        android:id="@+id/btn_2"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="Button2"
        app:layout_constraintLeft_toRightOf="@id/btn_1" />

</android.support.constraint.ConstraintLayout>


效果应该是这样的:

 

如果不设置 layout_goneMarginLeft 属性,就把 Button1 设置为 GONE,那么Button2 的位置肯定也会改变:

 

如果 Button2 设置了 app:layout_goneMarginLeft="120dp"(注意这个边距是 Button1 的 width 加上原先的左边距,所以一般使用这个属性的话,需要设置为 GONE 的控件的宽度或者高度或者两者应该是确定的),Button2 的位置是不会改变的:

 

2.4 Centering positioning and bias

设置控件居中的话就像 2.1 中的 Button1一样即可:

<?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"
    tools:context="com.qinshou.constraintlayoutdemo.MainActivity">

    <Button
        android:id="@+id/btn_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

 

有一个特殊的点需要说明一下,在 ConstrainiLayout 中,宽高除了设置为 wrap_content 和 match_parent 外,还可以设置为 0dp,这个 0dp 有点类似与 match_parent,但是 match_parent 是填充满父布局,而 0dp 是填充满约束规则。

 

bias表示偏移率,有 app:layout_constraintHorizontal_bias 和 app:layout_constraintVertical_bias 两个属性,分别表示水平方向的偏移和垂直方向的偏移,取值范围是 0.0~1.0,0.5 表示不偏移。

 

3 GuideLine

引导线,相当于一个参照物,如果我们要实现这样一个效果:

 

需要两个按钮都居中,一个在左,一个在右,如果普通的布局精确控制起来肯定很麻烦,ConstrainiLayout 中出现的新控件 GuideLine 就可以很方便的实现,GuideLine 有水平和垂直两个方向的,我们可以点这里添加 GuideLine:

 

也可以在 XML 代码中写:

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

 

GuideLine 默认是 GONE 的,设置它的位置一般可以通过三个属性:android:orientation、layout_constraintGuide_begin、layout_constraintGuide_end、layout_constraintGuide_percent,layout_constraintGuide_percent 的取值范围是0.0~1.0,在添加了 GuideLine 后我们再让两个 Button 分别一个右边对齐 GuideLine 的左边,另一个左边对齐 GuideLine 的右边就可以实现上面的效果:


 

4 小结

ConstrainiLayout 就像是一个强化版的RelativeLayout,已经出来了这么久我才接触它真是罪过,时刻接收新东西也是程序猿必备的素质之一,我感觉之前我就是用到什么才去学习什么,然后看到些炫酷的 UI 效果,感点兴趣才会去主动学习,其实很多新特性有可能让我们在开发中更方便,或者更需要注意是否会有什么 Bug,比如 Android 6.0 后的权限问题。所以无论什么时候,程序猿都不能停止学习的脚步。

 

;