Android开发经验谈Android技术知识Android开发

ConstraintLayout 约束布局例子讲解 (持续更新)

2018-04-03  本文已影响697人  zhongjh

2016年google就已经公布了这个约束布局ConstraintLayout。

但是时至现在2018年,还是很多人在使用普遍的LinearLayout或者RelativeLayout。有的可能会用到百分比布局,但是还是很少很少用到。我觉得非常有必要普及这方面的内容,并且这个对于提高性能,是有作用的

唯一副作用是学习成本高、相对于其他普通布局完成的速度可能也会慢

我最近也开始涉及学习这方面,发现确实如果不通过好好的例子来写的,确实很难上手。
所以出了以下内容,让大家更快更容易了解!

首先先跟大家共享我搜到的文章:
https://blog.csdn.net/lmj623565791/article/details/78011599?utm_source=tuicool&utm_medium=referral
https://blog.csdn.net/guolin_blog/article/details/53122387
https://segmentfault.com/a/1190000009536640?utm_source=tuicool&utm_medium=referral

再列出我觉得有参考性的demo,github上找的
https://github.com/googlesamples/android-ConstraintLayoutExamples
https://github.com/vtthach/20170704_Sample_ConstraintLayout

属性作用:

以前RelativeLayout的约束有两种:

参数取值是 ID(@id/button1)代表约束1、3, 或者 字符串"parent" 代表约束2:

RelativeLayout 对应父类 RelativeLayout 对应其他view ConstraintLayout
android:layout_alignParentLeft="true" android:layout_alignLeft app:layout_constraintLeft_toLeftOf 与指定View的左边界一致
android:layout_alignParentStart="true" android:layout_alignStart app:layout_constraintStart_toStartOf
android:layout_alignParentTop="true" android:layout_alignTop app:layout_constraintTop_toTopOf 与指定View的上边界一致
android:layout_alignParentRight="true" android:layout_alignRight app:layout_constraintRight_toRightOf
android:layout_alignParentEnd="true" android:layout_alignEnd app:layout_constraintEnd_toEndOf
android:layout_alignParentBottom="true" android:layout_alignBottom app:layout_constraintBottom_toBottomOf 与指定View的下边界一致
android:layout_centerHorizontal="true" app:layout_constraintStart_toStartOf="parent" 和 app:layout_constraintEnd_toEndOf="parent"
android:layout_centerVertical="true" app:layout_constraintTop_toTopOf="parent" 和 app:layout_constraintBottom_toBottomOf="parent"
android:layout_centerInParent="true" app:layout_constraintStart_toStartOf="parent", app:layout_constraintTop_toTopOf="parent", app:layout_constraintEnd_toEndOf="parent", 和 app:layout_constraintBottom_toBottomOf="parent"
android:layout_below app:layout_constraintTop_toBottomOf 在指定View的下方
android:layout_toEndOf app:layout_constraintStart_toEndOf 在指定View的右边
android:layout_toRightOf app:layout_constraintLeft_toRightOf 在指定View的右边
android:layout_above app:layout_constraintBottom_toTopOf 在指定View的上方
android:layout_toStartOf app:layout_constraintEnd_toStartOf 在指定View的左边
android:layout_toLeftOf app:layout_constraintRight_toLeftOf 在指定View的左边
android:layout_alignBaseline app:layout_constraintBaseline_toBaselineOf
组合属性作用:
ConstraintLayout 组合属性 解释
app:layout_constraintEnd_toStartOf="@+id/vLine", app:layout_constraintTop_toTopOf="@+id/vLine", app:layout_constraintBottom_toBottomOf="@+id/vLine" 这个是基于vLine控件的左边,并且完全的中心对齐
app:layout_constraintBottom_toBottomOf="@+id/vLine" app:layout_constraintStart_toEndOf="@+id/vLine" app:layout_constraintTop_toTopOf="@+id/vLine" 同上,这次是在右边并且中心对齐
1.首先完成顶部第一个图片:
image.png

添加以下两个属性

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

即可完成居中,因为左边约束了,右边也约束了。可以通俗的理解为左边和右边用相同的力道(我这样说是因为下面会介绍可以控制哪边用的力道大小)都相扯约束,自然居中了。
如果第一个图片不添加

app:layout_constraintTop_toTopOf="parent"

则这个相距属性android:layout_marginTop="16dp"是不会触发的。

所以总结第一个图片:

<ImageView
        android:id="@+id/imgIcon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginTop="16dp"
        android:src="@drawable/ic_security_lock"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="ContentDescription" />
2.接着完成顶部第二个控件:
image.png

首先直奔主题,关键的一个属性:

layout_constraintTop_toBottomOf 

按照我的理解则是约束上面并且位于该约束控件的下面
同时为了居中,也是添加约束父布局的左边和右边,所以最终是

<TextView
        android:id="@+id/txtMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="@string/please_enter_your_4_bit_password"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imgIcon" />
3.接着是比较困难的第三个控件布局
image.png

首先我们按照上面所了解的,先分别添加4个控件


image.png

第一个控件,居左并且在第二个控件的下面。第二个控件在第一个控件和第三个控件的中间,第三个控件一样,只有最后一个第四个控件在最右边。

<ImageView
        android:id="@+id/imgOne"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="24dp"
        android:src="@drawable/pin_code_round_empty"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtMessage"
        tools:ignore="ContentDescription" />

<ImageView
        android:id="@+id/imgTwo"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="24dp"
        android:src="@drawable/pin_code_round_empty"
        app:layout_constraintLeft_toRightOf="@+id/imgThree"
        app:layout_constraintRight_toLeftOf="@+id/imgOne"
        app:layout_constraintTop_toBottomOf="@+id/txtMessage"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/imgThree"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="24dp"
        android:src="@drawable/pin_code_round_empty"
        app:layout_constraintLeft_toRightOf="@+id/imgTwo"
        app:layout_constraintRight_toLeftOf="@+id/imgFour"
        app:layout_constraintTop_toBottomOf="@+id/txtMessage"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/imgFour"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="24dp"
        android:src="@drawable/pin_code_round_empty"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtMessage"
        tools:ignore="ContentDescription" />

那么剩下一个问题如何让他们居中呢?很简单,第一个控件添加

app:layout_constraintRight_toLeftOf="@+id/imgFour"

大意是居左,跟右边的第四个控件约束,变成这样


image.png

然后第四个控件添加该属性

app:layout_constraintLeft_toRightOf="@+id/imgOne"

最终便可以居中了

4.接着是下面的百分比布局

首先完成百分比布局之前,我们需要先明确大体布局。如上面的布局,横布局需要分成三等份,竖布局需要分成四等份。然后就开始创建参考线了。

4.1首先为了铺满这个百分比,要先创建多一个ConstraintLayout布局,基于txtForget控件的下面。
<android.support.constraint.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtForget">
4.2开始创建参考线。
Preview创建Guideline

创建竖线3条

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

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

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

创建横线4条

<android.support.constraint.Guideline
            android:id="@+id/guideline1H25"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.25" />

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H50"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.50" />

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H75"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.75" />

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H100"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="1" />

创建完所需要的参考线之后如图所示:

image.png
4.3接下来我们只要负责把需要放的控件放进参考线里面居中即可

让我们看看最重要的4个属性

app:layout_constraintBottom_toTopOf="@+id/guideline1H25"
            app:layout_constraintEnd_toStartOf="@+id/guidelineV33"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"

app:layout_constraintStart_toStartOf:表示与指定View的左边界一致,如果是parent则是父控件最左边
app:layout_constraintEnd_toStartOf:在指定View的左边
app:layout_constraintBottom_toTopOf:在指定View的上方
app:layout_constraintTop_toTopOf:与指定View的上边界一致,如果是parent则是父控件的最上边

那么把每个控件都放进去,最终百分比的代码:

<android.support.constraint.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtForget">

        <TextView
            android:id="@+id/txtOne"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:tag="1"
            android:text="1"
            android:textSize="32sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline1H25"
            app:layout_constraintEnd_toStartOf="@+id/guidelineV33"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txtTwo"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:tag="2"
            android:text="2"
            android:textSize="32sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline1H25"
            app:layout_constraintEnd_toStartOf="@+id/guidelineV66"
            app:layout_constraintStart_toEndOf="@+id/txtOne"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txtThree"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:tag="3"
            android:text="3"
            android:textSize="32sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline1H25"
            app:layout_constraintEnd_toStartOf="@+id/guidelineV100"
            app:layout_constraintStart_toStartOf="@+id/guidelineV66"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txtFour"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:tag="4"
            android:text="4"
            android:textSize="32sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline1H50"
            app:layout_constraintEnd_toStartOf="@+id/guidelineV33"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline1H25"
            tools:ignore="HardcodedText" />

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

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

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

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H25"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.25" />

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H50"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.50" />

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H75"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.75" />

        <android.support.constraint.Guideline
            android:id="@+id/guideline1H100"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="1" />

    </android.support.constraint.ConstraintLayout>
image.png

请注意,app:layout_constraintStart_toStartOf和app:layout_constraintLeft_toLeftOf有区别的,具体可以在改演示中的百分比修改就知道具体区别了。

5、利用Barrier完美实现“多对象约束”

例子布局

类似这样的布局,中间这条线是在左边两个文本框以及右边两个文本框的中间。广州黄埔的文字或者江苏南京的文字如果过长,中间的一条线都会往下移动,例如这样:


image.png

或者这样:


image.png
那么如何把这两个TextView对象当成一个对象来看待呢,很简单,如下代码:
        <android.support.constraint.Barrier
            android:id="@+id/barrier7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="bottom"
            app:constraint_referenced_ids="tvDeparture,tvDestination" />

最后把这个Barrier当成一个对象对待即可

app:layout_constraintTop_toBottomOf="@+id/barrier7"

6、待编辑的其他属性

<android.support.constraint.ConstraintLayout ...>
  <TextView
    android:id="@+id/text1" ... />
  <TextView
    android:id="@+id/text2" ... />
 <android.support.constraint.Group
            android:id="@+id/group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
    app:constraint_referenced_ids=”text1,text2" />
</android.support.constraint.ConstraintLayout>

[图片上传失败...(image-e0b4d2-1523179128704)]

总而言之,约束布局的能力正在变得越来越强大。

上一篇下一篇

猜你喜欢

热点阅读