ConstractLayout遇到的坑

Posted 且听真言

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ConstractLayout遇到的坑相关的知识,希望对你有一定的参考价值。

总结下ConstraintLayout的使用:

1.位置约束

因为ConstraintLayout采用约束的方式控制控件的位置,所以至少要保证水平和垂直方向都至少有一个约束才能确定控件的位置。

例如让TextView的顶部和界面顶部对齐,左部和界面左部对齐。

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView的顶部和界面顶部对齐,左部和界面左部对齐"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

  • app:layout_constraintStart_toStartOf="parent" 控件的开始方向 与 父容器的开始方向对齐。
  • app:layout_constraintTop_toTopOf="parent" 控件的顶部方向 与 父容器的顶部方向对齐。

使用start和end来表示左和右是为了考虑别的国家的习惯,有的国家开始方向是右,所以使用start和end可以兼容这种情况。

记忆的思路是:该控件的??方向在哪个控件的??方向。

再以TextView为例:

app:layout_constraintTop_toTopOf="parent"           TextView的顶部和parent的顶部对齐
app:layout_constraintBottom_toBottomOf="parent"     TextView的底部和parent的底部对齐
app:layout_constraintLeft_toLeftOf="parent"         TextView的左边和parent的左边对齐
app:layout_constraintRight_toRightOf="parent"       TextView的右边和parent的右边对齐
app:layout_constraintStart_toStartOf="parent"       TextView的开始位置和parent的开始位置对齐
app:layout_constraintEnd_toEndOf="parent"           TextView的结束位置和parent的结束位置对齐
app:layout_constraintTop_toBottomOf="parent"        TextView的顶部位置在parent的底部位置
app:layout_constraintStart_toEndOf="parent"         TextView的开始位置在parent的结束为止

 

2.基线对齐

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="100"
        android:textSize="20sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="$"
        app:layout_constraintBaseline_toBaselineOf="@+id/text_1"
        app:layout_constraintStart_toEndOf="@+id/text_1" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

3.角度约束

需要实现一个控件在某个控件的某个角度的位置,ConstraintLayout提供了角度位置相关的属性。

app:layout_constraintCircle=""         目标控件id
app:layout_constraintCircleAngle=""    对于目标的角度(0-360)
app:layout_constraintCircleRadius=""   到目标中心的距离

Text2 在 Text1的45度方向,距离为100dp

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="中间  Text"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintCircle="@+id/text_1"
        app:layout_constraintCircleAngle="45"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

4.百分比偏移

让控件在父布局的水平方向或垂直方向的百分之多少的位置

app:layout_constraintHorizontal_bias="parent"   根据父布局的 水平偏移 取值范围是0-1的小数
app:layout_constraintVertical_bias="parent"     根据父布局的 垂直偏移 取值范围是0-1的小数

 

控件Text_1在父布局水平方向偏移0.2(20%),垂直方向偏移0.8(80%)

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_1"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.8" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

控件Text_2在水平方向偏移0.2(20%),垂直方向偏移0.5(50%)

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_1"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.8" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_2"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/text_1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.2"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

5.控件内边距、外边距、GONE Margin

ConstraintLayout使用goneMargin属性,当依赖的目标view隐藏时,该属性生效,例如B被A依赖约束,当B隐藏时B会缩成一个点,自身的margin效果失效,A设置的goneMargin就会生效。

当Text_1显示时,Text_2goneMargin属性不生效。

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text2"
        app:layout_constraintBottom_toTopOf="@+id/text_1"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_goneMarginStart="100dp"
        app:layout_goneMarginTop="100dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

当Text_1隐藏之后,Text_1会缩成一个点,Text_2设置的goneMargin就会生效,start:100dp,bottom:200dp

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

    <TextView
        android:visibility="gone"
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text2"
        app:layout_constraintBottom_toTopOf="@+id/text_1"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_goneMarginStart="100dp"
        app:layout_goneMarginBottom="200dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

6.控件尺寸

  1. 6.1尺寸限制

在ConstraintLayout中有尺寸限制的属性,可以用来限制最大、最小宽高度,这些属性只有在给出的宽度或高度为wrap_content时才会生效。

android:minWidth=""   设置view的最小宽度
android:minHeight=""  设置view的最小高度
android:maxWidth=""   设置view的最大宽度
android:maxHeight=""  设置view的最大高度

TextView 的最小宽度和最大宽度,最小高度和最大高度。

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:minWidth="100dp"
        android:maxWidth="200dp"
        android:minHeight="100dp"
        android:maxHeight="200dp"
        android:singleLine="true"
        android:text="hahahhahahahahhahhhhhhhhhhhhhhhhhhhhhhhahahahhhah哈哈哈哈哈哈哈哈哈"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

  1. 6.2 0dp(MATCH_CONSTRAINT)

设置view的大小除了wrap_content、指定尺寸、match_parent外,还可以设置为0dp(MATCH_CONSTRAINT),并且0dp的作用会根据设置的类型而产生不同的作用,进行设置类型的属性是layout_constraintWidth_default和layout_constraintHeight_default,取值可为spread、percent、wrap。具体的属性及示例如下:

app:layout_constraintWidth_default="spread|percent|wrap"
app:layout_constraintHeight_default="spread|percent|wrap"

  • spread(默认):占用所有的符合约束的空间

下面的TextView的宽度适应了所有有效的约束空间,左右留出100dp,所以默认的效果是:自身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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="哈哈哈"
        app:layout_constraintWidth_default="spread"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

  • percent:按照父布局的百分比设置

percent模式将自身view的尺寸设置为父布局尺寸的一定比例,下面将TextView所展示的是宽度设置为父布局宽度的0.7(70%,取值是0-1的小数),该模式需要配合layout_constraintWidth_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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_1"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:text="哈哈"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.7" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="spread" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_1"
        app:layout_constraintWidth_default="wrap" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

两个控件作为对比,Text1宽度设置为wrap_content,宽度适应内容大小,并且设置了margin,但是显然宽度已经超过margin的设置值了,Text2宽度设置为0dp wrap模式,宽度适应内容大小,并且不会超过margin的设置值,也就是不会超过约束限制,这就是这两者的区别。

 

  • 再看一下wrap 与 spread的区别:

从下面的例子可以发现:wrap会影响到  TextView内容的排列。

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="spread" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_1"
        app:layout_constraintWidth_default="wrap" />

</androidx.constraintlayout.widget.ConstraintLayout>

Google还提供了两个属性用于强制约束:

<!--  当一个view的宽或高,设置成wrap_content时  -->
app:layout_constrainedWidth="true|false"
app:layout_constrainedHeight="true|false"

将Text1设置了强制约束,展示出的效果和Text2就一样了。

 

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        app:layout_constrainedWidth="true"
        android:text="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="spread" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:layout_marginEnd="100dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_1"
        app:layout_constraintWidth_default="wrap" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

0dp还有一些其他的独特属性用于设置尺寸的大小限制

app:layout_constraintWidth_min=""   0dp下,宽度的最小值
app:layout_constraintHeight_min=""  0dp下,高度的最小值
app:layout_constraintWidth_max=""   0dp下,宽度的最大值
app:layout_constraintHeight_max=""  0dp下,高度的最大值

7.比例宽高(Ratio)

ConstraintLayout中可以对宽高设置比例,前提是至少有一个约束维度设置为0dp,这样比例才会生效,该属性可使用两种设置:

  • 1. 浮点值,表示宽度和高度之间的比率
  • 2. 宽度:高度,表示宽度和高度之间形式的比率
app:layout_constraintDimensionRatio="2:1"  宽高比例2: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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_1"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_marginTop="20dp"
        android:background="@color/colorAccent"
        app:layout_constraintDimensionRatio="1:2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/text_1" />

    <TextView
        android:id="@+id/text_3"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_marginTop="20dp"
        android:background="@color/colorAccent"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/text_2" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

8.Chains(链)

将许多个控件在水平或者垂直方向,形成一条链,用于平衡这些控件的位置,形成一条链要求链中的控件在水平或者垂直方向,首尾互相约束,这样就可以形成一条链。

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toStartOf="@+id/text_2"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toStartOf="@id/text_3"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/text_2"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Text_1、Text_2、Text_3,三个控件在水平方向上首尾互相约束,这样就形成了一条水平链,默认的模式是spread,均分剩余空间,使用layout_constraintHorizontal_chainStyle和layout_constraintVertical_chainStyle分别对水平和垂直链设置模式,模式可选的值有:spread、packed、spread_inside

  • spread_inside:Text2两侧的Text1与Text3贴到两边,剩余的空间站均分空间
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toStartOf="@+id/text_2"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toStartOf="@id/text_3"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/text_2"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

  • packed:所有控件贴紧局中。
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toStartOf="@+id/text_2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@android:color/black"
        app:layout_constraintEnd_toStartOf="@id/text_3"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@android:color/holo_blue_dark"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/text_2"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

  • Chains(链)支持weight(权重)的配置,使用layout_constraintHorizontal_weight和layout_constraintVertical_weight进行设置链元素的权重

packed与layout_constraintHorizontal_weight一起使用:

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toStartOf="@+id/text_2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_weight="3"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@android:color/black"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintEnd_toStartOf="@id/text_3"
        app:layout_constraintStart_toEndOf="@+id/text_1"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_3"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@android:color/holo_blue_dark"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@+id/text_2"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 9.辅助类   

ConstraintLayout为了解决嵌套问题还提供了一系列的辅助控件。

  • Guideline(参考线)

Guideline是一条参考线,可以帮助开发者进行辅助定位,并且实际上它并不会真正显示在布局中,Guideline可以用来做一些百分比分割之类的需求,Guideline有水平和垂直方向之分,位置可以使用针对父级的百分比或者针对父级位置的距离

android:orientation="horizontal|vertical"  辅助线的对齐方式
app:layout_constraintGuide_percent="0-1"   距离父级宽度或高度的百分比(小数形式)
app:layout_constraintGuide_begin=""        距离父级起始位置的距离(左侧或顶部)
app:layout_constraintGuide_end=""          距离父级结束位置的距离(右侧或底部)

下面代码中设置了一条水平方向位置在父级垂直方向0.3(30%)的Guideline,Text1的顶部依赖于Guideline,这样无论布局如何更改,Guideline的位置始终都会是父级垂直方向30%的位置。

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

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.3">

    </androidx.constraintlayout.widget.Guideline>

    <TextView
        android:id="@+id/text_1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/guideline"

        />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

  • Barrier(屏障)

Barrier不会出现在实际的布局中,它的作用是形成一个屏障、障碍。这里借助constraintlayout网站(https://constraintlayout.github.io/basics/barriers.html)来讲解Barrier。

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


    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:text="哈我是Text1"
        android:background="@color/colorAccent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:text="哈哈哈我是text2"
        android:background="@android:color/holo_green_light"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_1" />

    <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="text_1,text_2" />

    <TextView
        android:id="@+id/text_3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:background="@android:color/darker_gray"
        android:text="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
        app:layout_constraintStart_toEndOf="@+id/barrier"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

左边的Text1和Text2;右边的Text3。Text3被限制在Text1的末尾。

然而,因为在不同的情况下,Text1中的文本可能比Text2中的文本长,或者Text2中的文本比Text1长:

Barriers的配置属性如下:

<!--  用于控制Barrier相对于给定的View的位置  -->
app:barrierDirection="top|bottom|left|right|start|end"  

<!--  取值是要依赖的控件的id,Barrier将会使用ids中最大的一个的宽/高作为自己的位置  -->
app:constraint_referenced_ids="id,id"

Barrier会自动位于较宽的那个Text后面,也就间接让Text3也位于了正确的位置。

10.Flow(流式虚拟布局)

Flow是用于构建链的新虚拟布局,当链用完时可以缠绕到下一行甚至屏幕的另一部分。当您在一个链中布置多个项目时,这很有用,但是您不确定容器在运行时的大小。您可以使用它来根据应用程序中的动态尺寸(例如旋转时的屏幕宽度)构建布局。Flow是一种虚拟布局。在ConstraintLayout中,虚拟布局(Virtual layouts)作为virtual view group的角色参与约束和布局中,但是它们并不会作为视图添加到视图层级结构中,而是仅仅引用其它视图来辅助它们在布局系统中完成各自的布局功能。

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

    <TextView
        android:id="@+id/txt_1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text1" />

    <TextView
        android:id="@+id/txt_2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text2" />

    <TextView
        android:id="@+id/txt_3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text3" />

    <TextView
        android:id="@+id/txt_4"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="Text4" />

    <TextView
        android:id="@+id/txt_5"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text5" />

    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="txt_1,txt_2,txt_3,txt_4,txt_5"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

11.链约束

Flow的constraint_referenced_ids关联的控件是没有设置约束的,这一点和普通的链是不一样的,这种排列方式是Flow的默认方式none,我们可以使用app:flow_wrapMode=""属性来设置排列方式,并且我们还可以使用flow_horizontalGap和flow_verticalGap分别设置两个view在水平和垂直方向的间隔。

app:flow_wrapMode="none"

none为默认值,所有引用的view形成一条链,水平居中,超出屏幕两侧的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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txt_1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text1" />

    <TextView
        android:id="@+id/txt_2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text2" />

    <TextView
        android:id="@+id/txt_3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text3" />

    <TextView
        android:id="@+id/txt_4"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="Text4" />

    <TextView
        android:id="@+id/txt_5"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text5" />


    <TextView
        android:id="@+id/txt_6"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text6" />

    <TextView
        android:id="@+id/txt_7"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text7" />

    <TextView
        android:id="@+id/txt_8"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="Text8" />

    <TextView
        android:id="@+id/txt_9"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text9" />

    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="txt_1,txt_2,txt_3,txt_4,txt_5,txt_6,txt_7,txt_8,txt_9"
        app:flow_wrapMode="none"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

  • app:flow_wrapMode="chain"

chain将所引用的view形成一条链,超出部分会自动换行,同行的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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txt_1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text1" />

    <TextView
        android:id="@+id/txt_2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text2" />

    <TextView
        android:id="@+id/txt_3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text3" />

    <TextView
        android:id="@+id/txt_4"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="Text4" />

    <TextView
        android:id="@+id/txt_5"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text5" />


    <TextView
        android:id="@+id/txt_6"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text6" />

    <TextView
        android:id="@+id/txt_7"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text7" />

    <TextView
        android:id="@+id/txt_8"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="Text8" />

    <TextView
        android:id="@+id/txt_9"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text9" />

    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="txt_1,txt_2,txt_3,txt_4,txt_5,txt_6,txt_7,txt_8,txt_9"
        app:flow_wrapMode="chain"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

  • app:flow_wrapMode="aligned"

aligned:将所引用的view形成一条链,但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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txt_1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text1————————————————————————————————————" />

    <TextView
        android:id="@+id/txt_2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text2" />

    <TextView
        android:id="@+id/txt_3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text3" />

    <TextView
        android:id="@+id/txt_4"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="Text4" />

    <TextView
        android:id="@+id/txt_5"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="Text5" />


    <TextView
        android:id="@+id/txt_6"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:text="Text6" />

    <TextView
        android:id="@+id/txt_7"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_blue_dark"
        android:gravity="center"
        android:text="Text7" />

    <TextView
        android:id="@+id/txt_8"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@androi

以上是关于ConstractLayout遇到的坑的主要内容,如果未能解决你的问题,请参考以下文章

如何用ffmpeg截取视频片段&截取时间不准确的坑

Blender制作多个动画片段时踩的坑

初学python 遇到的坑

python appium server代码调起和关闭遇到的坑

Android emulator中C代码的调试——gdb/gdbservers时遇到的坑

Unity 使用xLua遇到的坑