使用 ConstraintLayout

1.前言

你是不是一直不敢用ConstraintLayout,是以为属性太多太复杂?你心理上的惰性,畏惧它。它其实很好用很强大,如果要用就需要一个入门的敲门砖

2.了解ConstraintLayout

特点:简化操作、解决布局嵌套、自适应布局、可百分比布局、可同时替代线性布局LinearLayout和相对布局RelativeLayout的强大功能

3.基本用法

ConstraintLayout的位置约束属性如下,属性值可以是parent或者@+id/兄弟组件的id:
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_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
Layout_constraintEnd_toEndOf
怎么这么多12个属性,相对布局你都会,这个就不用害怕理解一下就明白了,相对布局不就是top,bottom,left,right四个属性吗,看单词只不过多了start和end(为了支持阿拉伯国家),这里你也可以当成left和right,效果一样。推荐使用start和end.下面就解析一下这些属性。

3.1 看一个布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
先理解一下这个button控件,它使用了layout_constraintStart_toStartOf、layout_constraintBottom_toBottomOf和
layout_constraintTop_toTopOf
意思:parent表示父布局,而且使用约束布局必须在水平和垂直都添加约束,不然不完整。
button的左边和父布局的左边对齐,
button的下面边和父布局的下面边对齐,
button的上面的边和父布局的上面边对齐
从显示效果图可以看到第一个左对左效果有了,又由于要求控件上对上和下对下就会出现在中间的效果。

3.2再看一个布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintTop_toTopOf="@+id/button"
     />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
它使用了layout_constraintStart_toEndOf和
layout_constraintTop_toTopOf
意思:"@+id/button表示兄弟布局
button1的左边和兄弟布局的右边对齐,
button1的上面边和兄弟布局的上面边对齐,
从显示效果图可以看到效果都有了,真的好强大,下面再讲布局的时候不用详细讲了,不用死记硬背,理解了这个就基本的会了。

3.3 想要button1在button的下面又在右边怎么做呢

很简单,只要知道button1最终的效果是button1的左边在button右边(layout_constraintStart_toEndOf)和button1的上面在button下面(layout_constraintTop_toBottomOf)就可以了。效果
在这里插入图片描述
如果改成button1在button的上面和右边呢,及垂直方向上button1的下面在button的上边(layout_constraintBottom_toTopOf)和水平方向上button1的左边在button的右边(layout_constraintStart_toEndOf),简单吧,你悟了吧

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintBottom_toTopOf="@+id/button"
     />

</androidx.constraintlayout.widget.ConstraintLayout>

3.3 下一个效果走起

在这里插入图片描述
这种效果怎么实现呢,就是水平方向上让button1的位置处在button剩余宽度的中心。分析一下:刚才让button1在button的右下已经分析过,及button1上对button下,button1左对button右,还记不记得最前面button垂直居中怎么做的就是button和父布局,上对上,下对下,它居中了。现在也一样,button1想居中的宽度的左边界已经有了,右边界就是父布局的最右边,及实现效果需要button1使用这三个合起来就行了。layout_constraintStart_toEndOf,layout_constraintTop_toBottomOf,layout_constraintEnd_toEndOf,完美。但是注意一个细节是推荐你用start和end,在一个控件中你如果用了left和right那一定是成套用,别这用一个那用一个用乱了,效果也没出来。比如就难咱这个布局来说你先用了layout_constraintStart_toEndOf和layout_constraintTop_toBottomOf,最后一个你突然用layout_constraintRight_toRightOf,效果就不会出来。

3.4 下一个效果

如果想让button1永远在button的中间位置怎么做呢,你可以利用上面的用到的约束左右边界达到居中的效果。这里居中的左右边界就是button的左右边界。

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintStart_toStartOf="@+id/button"
        app:layout_constraintTop_toBottomOf="@+id/button"
        app:layout_constraintEnd_toEndOf="@id/button"
     />

</androidx.constraintlayout.widget.ConstraintLayout>

效果
在这里插入图片描述
如果button1相对于兄弟布局button约束布局写成下面这三个会是什么效果呢
app:layout_constraintStart_toEndOf=“@+id/button”
app:layout_constraintTop_toBottomOf=“@+id/button”
app:layout_constraintEnd_toEndOf=“@id/button”
没错,就是你想的那样button1永远会在button右边为中心点的位置,即
在这里插入图片描述

3.4 layout_constraintBaseline_toBaselineOf

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="56sp"
        android:text="textview"
        android:background="#097"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="36sp"
        android:text="textview1"
        android:background="#876"
        app:layout_constraintStart_toEndOf="@+id/textview"
        app:layout_constraintBottom_toBottomOf="@+id/textview"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

下面是效果,可以看出,这两个textview并不是真的对齐而是底边对齐了
在这里插入图片描述
这个时候textview1加上 属性app:layout_constraintBaseline_toBaselineOf=“@+id/textview”
看下效果
在这里插入图片描述
学到这里相对布局RelativeLayout的功能都能用约束布局搞定了,加上baseline一共13个属性,强大了很多倍。

3.5 margin 和 goneMargin

ConstraintLayout 中子组件的使用和普通布局是一样的,唯一有区别的地方是,必须存在约束margin才会生效:
android:layout_margin
android:layout_marginStart
android:layout_marginLeft
android:layout_marginTop
android:layout_marginEnd
android:layout_marginRight
android:layout_marginBottom
注意一定要有约束,比如

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="48sp"
        android:text="textview"
        android:background="#097"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
    <TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="36sp"
        android:text="textview1"
        android:background="#876"
        app:layout_constraintStart_toEndOf="@+id/textview"
        app:layout_constraintTop_toTopOf="@+id/textview"
        android:layout_marginStart="16dp"
         />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
要实现这种效果如果你在textview控件上设置 android:layout_marginEnd="16dp"不会有任何效果,因为没有对textview的右边的约束,在textview1上加上android:layout_marginStart="16dp"就出现了上图的效果。

除了普通的margin外,还有goneMargin,当 当前组件对应边的约束组件隐藏时会生效,显示时不生效。例如下面

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="48sp"
        android:text="textview"
        android:background="#097"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
    <TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="36sp"
        android:text="textview1"
        android:background="#876"
        app:layout_goneMarginStart="100dp"
        app:layout_constraintStart_toEndOf="@+id/textview"
        app:layout_constraintTop_toTopOf="@+id/textview"
         />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
当textview 显示的时候layout_goneMarginStart就会无效。

3.6 水平和垂直方向的百分比布局

layout_constraintHorizontal_bias和layout_constraintVertical_bias
如果想有效果一定得有约束,不然没有效果。
布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.3"
        app:layout_constraintVertical_bias="0.4"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

效果
在这里插入图片描述
为了更好理解在加一个button1按钮

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button11111111111111111111111"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.3"
        app:layout_constraintVertical_bias="0.4"
        />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button1"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintEnd_toStartOf="@+id/button"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.8"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

3.7 角度约束

ConstraintLayout可以让我们轻松的实现一个控件在另一个控件的某个角度的某个位置。
你需要用到下面这些属性
layout_constraintCircle 角度中心组件的id
layout_constraintCircleAngle 角度(0-360)
layout_constraintCircleRadius 到中心的距离

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv0"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:text="0"
        android:textSize="32sp"
        android:textColor="@color/white"
        android:gravity="center"
        android:background="#097"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        />
    <TextView
        android:id="@+id/tv1"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:textSize="32sp"
        android:textColor="@color/white"
        android:text="1"
        android:gravity="center"
        android:background="#097"
        app:layout_constraintCircle="@id/tv0"
        app:layout_constraintCircleAngle="0"
        app:layout_constraintCircleRadius="100dp"
        />
    <TextView
        android:id="@+id/tv2"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:textSize="32sp"
        android:textColor="@color/white"
        android:text="2"
        android:gravity="center"
        android:background="#097"
        app:layout_constraintCircle="@id/tv0"
        app:layout_constraintCircleAngle="30"
        app:layout_constraintCircleRadius="100dp"
        />
    <TextView
        android:id="@+id/tv3"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:textSize="32sp"
        android:textColor="@color/white"
        android:text="3"
        android:gravity="center"
        android:background="#097"
        app:layout_constraintCircle="@id/tv0"
        app:layout_constraintCircleAngle="60"
        app:layout_constraintCircleRadius="100dp"
        />
    <TextView
        android:id="@+id/tv4"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:textSize="32sp"
        android:textColor="@color/white"
        android:text="4"
        android:gravity="center"
        android:background="#097"
        app:layout_constraintCircle="@id/tv0"
        app:layout_constraintCircleAngle="90"
        app:layout_constraintCircleRadius="100dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

3.8 0dp(MATCH_CONSTRAINT)与组件大小

设置view的大小我们可以使用wrap_content、指定尺寸、match_parent,ConstraintLayout还可以设置为0dp(MATCH_CONSTRAINT),
odp并不会使组件大小变为0,而是会因为不同的属性产生不同的效果,属性为:。
layout_constraintWidth_default
Layout_constraintHeight_default
要想使这两个属性生效,我们需要设置组件的layout_width=“0dp”或者layout_height=“0dp”
属性的取值可以是:
spread(默认值,占据所有可以占据的空间)
percent(父布局的百分比,代表是当前组件的大小是父布局大小的一定比例,需要配合layout_constraintWidth_percent使用,取值是0-1的小数,当设置layout_constraintWidth_percent后,layout_constraintWidth_default="percent"会被默认,即使我们已经设置了spread或者wrap)
wrap(大小自适应)
例如布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

效果
在这里插入图片描述
如果设置 app:layout_constraintWidth_default=“percent”
app:layout_constraintWidth_percent=“0.7”,效果
在这里插入图片描述

如果设置app:layout_constraintWidth_default=“wrap”,效果
在这里插入图片描述
在这里插入图片描述

3.9 Chains(约束链)

在水平或者垂直方向的全部控件,相邻的组件两两之间首尾互相约束(任何一个组件都要有两边的约束,少了一个都不能形成链),这样就可以形成一条链。

我们可以使用layout_constraintHorizontal_chainStyle、layout_constraintVertical_chainStyle分别对水平和垂直链设置模式,
模式值有:
spread(默认、所有的组件均分剩余空间)
Packed(所有组件贴紧居中)
spread_inside(两侧的控件在两边,中间的组件均分剩余空间)

layout_constraintHorizontal_chainStyle和layout_constraintVertical_chainStyle只有对水平链或者竖直链上的第一个组件设置有效。
收尾相互约束的效果如下所示

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/button1"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintEnd_toStartOf="@+id/button2"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button1"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
在button按钮设置 app:layout_constraintHorizontal_chainStyle="spread"就是图片效果,默认就是spread。
如果我们设置app:layout_constraintHorizontal_chainStyle=“packed”,效果如下:
在这里插入图片描述

如果我们设置app:layout_constraintHorizontal_chainStyle=“spread_inside”,效果如下:
在这里插入图片描述
当一条链中的组件使用layout_constraintWidth_default=“spread”,我们可以使用layout_constraintHorizontal_weight 和layout_constraintHorizontal_weight来设置组件在链中的权重,也就是占比。
要注意的是,如果设置的这两个属性,链的组件将会占满整条链的空间,weight和percent 是不同的。示例如下:

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/button1"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button1"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintEnd_toStartOf="@+id/button2"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintHorizontal_weight="3"
        android:text="Button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button1"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

3.10 0dp与宽高比例

这个属性很有用,以后不用自定义布局,也不用代码中实现图片变形计算啥的了

 <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline"
          android:layout_width="wrap_content"
          android:layout_height="0dp"
          app:layout_constraintGuide_percent="0.4"
          android:orientation="vertical"/>

这个控件可能很多不熟悉的就是辅助线,看效果
在这里插入图片描述
给textview添加一个 app:layout_constraintEnd_toEndOf=“@id/guideline”,看效果
在这里插入图片描述
ConstraintLayout中可以很简单的对宽高设置比例,使用的属性为layout_constraintDimensionRatio

1.要使用layout_constraintDimensionRatio属性要求layout_width、layout_height至少有一个设置为0dp。
2. 建议layout_width、layout_height至少有一个设置为0dp ,另外一个属性是具有明确的大小,包括match_parent、具体的尺寸值、0dp。这是因为我们有了宽高之间的比例,我们需要一个明确的宽度值或者高度值,去计算另一个值,如果我们设置成为wrap_content,会出现很多异常的情况,这是我们不愿看到的。
3. layout_constraintDimensionRatio属性的类型是一个字符串,属性值是
radio比例,就是m;n形式的字符串,是宽高比或者高宽比的意思。
除了直接写radio比例以外,我们还可以写成 ,前缀wh对我们计算会产生影响。
w,radio比例。
h,radio比例。

<?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:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/textview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="h,16:9"
        android:text="A"
        android:gravity="center"
        android:textSize="48sp"
        android:background="#097"
        app:layout_constraintEnd_toEndOf="@id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline"
          android:layout_width="wrap_content"
          android:layout_height="0dp"
          app:layout_constraintGuide_percent="0.8"
          android:orientation="vertical"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

3.11 Barrier(屏障)

和Guideline一样,也不会实际出现在布局中,作用是分隔布局。
想象一个场景:竖着两个文本框12,文本框12的长度未知,与两个文本框水平并行一个文本框3,文本框3要在文本框12的右边,此时正常的位置约束就有些尴尬。

它有两个属性:
app:constraint_referenced_ids=“id,id”
一组控件的id,id之间用逗号分隔,Barrier将会使用id中最大的一个的宽/高作为自己的位置
app:barrierDirection=“top|bottom|left|right|start|end”
用于控制Barrier相对于给定id的组件的位置
示例代码如下:

<?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:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:textSize="18sp"
        android:text="数据1数据"
        android:background="@color/purple_200"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:textSize="18sp"
        android:background="@color/purple_500"
        android:text="数据2数据2数据2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView1" />

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="textView2,textView1" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="0dp"
        android:background="@color/purple_700"
        android:layout_height="wrap_content"
        android:text="数据3数据3数据3数据3数据3数据3数据3数据3数据3数据3数据3"
        app:layout_constraintLeft_toRightOf="@+id/barrier"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

3.12 Placeholder(占位符)

Placeholder可以在布局中事先占据一个位置,在代码中使用Placeholder.setContentId(布局id),就可以让某个控件移动到此占位符中。
示例代码如下,效果可自行尝试:

<TextView
    android:id="@+id/tvUserName"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_200"
    android:text="用户姓名"
    android:textColor="@color/white"
    android:textSize="18sp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<androidx.constraintlayout.widget.Placeholder
    android:layout_width="100dp"
    android:id="@+id/placeholder"
    android:layout_height="100dp"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />


3.13 Flow流式布局

流式布局使我们经常用到的布局,广泛的用在列表(尤其是图片列表)、标签、分类展示等场景中,传统的流式布局 我们可以使用 RecyclerView重写LayoutManager实现、也可以使用Google比较经典的流式布局FlexboxLayout
实现,功能都很强大。
ConstraintLayout也提供了流式布局的实现。
Flow组件,他同样有一个constraint_referenced_ids属性,属性值也是组件的id,id之间用逗号分割,表示纳入流式布局的管理。
控制流式布局的样式:
flow_wrapMode设置排列方式
none(默认值):所有的组件并排,超出屏幕两侧的组件不可见
示例代码如下:

<TextView
    android:id="@+id/tvA"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_200"
    android:text="用户姓名"
    android:textColor="@color/white"
    android:textSize="18sp" />


<TextView
    android:id="@+id/tvB"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_500"
    android:text="男"
    android:textColor="@color/white"
    android:textSize="18sp" />

<TextView
    android:id="@+id/tvC"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_200"
    android:text="用户姓名"
    android:textColor="@color/white"
    android:textSize="18sp" />


<TextView
    android:id="@+id/tvD"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_500"
    android:text="男"
    android:textColor="@color/white"
    android:textSize="18sp" />
<TextView
    android:id="@+id/tvE"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_200"
    android:text="用户姓名"
    android:textColor="@color/white"
    android:textSize="18sp" />


<TextView
    android:id="@+id/tvF"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/purple_500"
    android:text="男"
    android:textColor="@color/white"
    android:textSize="18sp" />
<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF"

    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent">

</androidx.constraintlayout.helper.widget.Flow>


效果
在这里插入图片描述
chian:超出范围的组件会自动换行,不满一行的组件会平分宽度。
在这里插入图片描述
aligned:超出范围的组件会自动换行, 换行后从头排列。
其他的属性flow_horizontalGap 水平间隔flow_verticalGap 竖直间隔
上面的示例使用aligned并且增加app:flow_horizontalGap="2dp"app:flow_verticalGap=“5dp” 后效果:
在这里插入图片描述
当flow_wrapMode=“chain” 的时候,我们可以设置样式,样式和我们前面讲到的链是一样的。
app:flow_horizontalStyle=“packed|spread|spread_inside” 所有水平链的配置
app:flow_verticalStyle=“packed|spread|spread_inside” 所有垂直链的配置

app:flow_firstHorizontalStyle=“packed|spread|spread_inside” 第一条水平链的配置,其他条不生效
app:flow_firstVerticalStyle=“packed|spread|spread_inside” 第一条垂直链的配置,其他条不生效
app:flow_lastHorizontalStyle=“packed|spread|spread_inside” 最后一条水平链的配置,其他条不生效
app:flow_lastVerticalStyle=“packed|spread|spread_inside” 最后一条垂直链的配置,其他条不生效

我们分别添加app:flow_horizontalStyle=“packed|spread|spread_inside” 效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
low_maxElementsWrap可以设置每行可布局组件最大的数量,当我们设置
app:flow_maxElementsWrap="3"的时候可以看到:
在这里插入图片描述
ConstraintLayout的用法实在太多,尤其是2.0以后,这里暂时整理这么多,后续慢慢补充。
本文参考了bilibi视频地址:【阿里P7进阶学习】使用 ConstraintLayout 构建自适应界面
参考其他csdn博客地址:Android ConstraintLayout用法全解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值