Android ConstraintLayout的易懂教程

2,873 阅读4分钟

1. 简介

ConstraintLayout是Google提供的一种ViewGrop,因为它不用像LinearLayout那样嵌套的方式实现复杂的Layout,使得ConstraintLayout更加易写易读,还能让App的性能有所提高(因为少了层级嵌套,所以绘制时的性能损耗也会减少)。

ConstraintLayout如其名字,它是通过设置显示限制来决定View的显示位置。

2. 使用方法

2.1 引入外部库和设置ViewGroup

正常情况下,新建一个工程时会自动加入ConstraintLayout的库,如果没有则需要手动加入。

implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

接下来需要把layout文件中的根ViewGroup设置成ConstraintLayout

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    ......
</androidx.constraintlayout.widget.ConstraintLayout>

2.2 设置基本的限制条件

介绍一下决定View位置的几种ConstraintLayout的限制条件。

  • app:layout_constraintTop_toTopOf //该View的上部与指定的View上部位置一致
  • app:layout_constraintTop_toBottomOf //该View的上部与指定的View下部位置一致
  • app:layout_constraintBottom_toBottomOf
  • app:layout_constraintBottom_toTopOf
  • app:layout_constraintStart_toStartOf
  • app:layout_constraintStart_toEndOf
  • app:layout_constraintEnd_toEndOf
  • app:layout_constraintEnd_toStartOf

需要注意的是除了设置ViewID,还可以设置parentparent是指显示界面。 还有比如同时设置左右限制,则View会居中,就像两端被绳子拉紧居中似的。

如果想要左侧或者右侧倾斜,则需要加入权重。

app:layout_constraintHorizontal_bias="0.2"

还有如果要设置View的margin需要用下面的方法。

  • android:layout_marginTop
  • android:layout_marginButtom
  • android:layout_marginStart
  • android:layout_marginEnd

举一个例子,大家应该很快就会理解了。

        <TextView
            android:id="@+id/textView10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="50dp"
            android:text="TextView10"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintStart_toStartOf="parent" />

2.3 Barrier

有时候我们会有根据多个View中最右端的位置,决定另一个View的位置。如果使用ConstraintLayoutBarrier就容易实现。

首先增加一个Barrier,并且设置如下的设置。

2.3.1 Barrier的方向

需要决定要把Barrier放置在相对于View的哪个位置。根据上述需求:

app:barrierDirection="end"

除了end,还有start,top,bottom

2.3.2 引用的ID

还需要设置对限制起作用的引用ID。如果我们是需要根据两个TextView中最右端的位置,来决定另一View的位置时,可以写成如下的代码。

app:constraint_referenced_ids="textView1,textView2"
2.3.3 例
        <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="textView1,textView2" />

2.4 GuideLine

如果在一个View中有很多组件需要设置一样的margin的时候可以使用GuideLine,使其往后的整体修改更容易,代码更加简洁。

GuideLine正如它的名字,它是一个参考线,但它是隐形的。GuideLine本身是不会显示在View中的,它只是作为参考线,统一各个View的margin。

2.4.1 设置参考线的方向

我们需要设置参考线是纵向还是横向的。如下代码。

android:orientation="vertical"

vertical是纵向,horizontal是横向。

2.4.2 设置参考线的位置

通过使用基本限制条件来设置参考线的位置。但这里有一个特别值得注意的一点是,margin的设置是不能用普通的限制条件,需要用其专门的margin限制条件。

margin的限制条件:

  • app:layout_constraintGuide_end
  • app:layout_constraintGuide_start
  • app:layout_constraintGuide_top
  • app:layout_constraintGuide_bottom

下面的代码的意思是,把参考线设置在离界面右端的30dp的位置。

app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintGuide_end="30dp"
2.4.3 设置其他View的位置限制条件

剩下的就是把View的位置限制条件设置成GuideLine即可。

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World1!"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@id/guideline1" />
2.4.4 整体代码
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintGuide_begin="30dp" />
         
         <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World1!"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@id/guideline1" />
2.4.5 截图

2.5 ChainStyle

根据上面的叙述,对View设置左右的限制时,该View会居中显示。但是如果两个View想要贴在一起显示,就需要用到ChainStyle

ChainStyle一共有三种类型。

  • spread_inside
  • spread
  • packed

当然根据方向分为纵向和横向的ChainStyle

  • layout_constraintHorizontal_chainStyle
  • layout_constraintVertical_chainStyle

使用ChainStyle时有一个注意点是,需要对View的两侧都要设置限制,如果缺少限制条件,ChainStyle就不会起作用。

2.5.1 spread_inside

spread_inside是两边View贴近边缘,中间居中。

2.5.2 spread

spread是所有View居中。

2.5.3 packed

packed是所有的View都贴在一起。

2.5.4 例
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="150dp"
            android:text="TextView1"
            app:layout_constraintEnd_toStartOf="@id/textView2"
            app:layout_constraintHorizontal_chainStyle="packed"
            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:layout_marginTop="150dp"
            android:text="TextView2"
            app:layout_constraintEnd_toStartOf="@id/textView3"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toEndOf="@id/textView1"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="150dp"
            android:text="TextView3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toEndOf="@id/textView2"
            app:layout_constraintTop_toTopOf="parent" />

3. 其他

除了上述内容,还有很多关于ConstraintLayout的其他内容,因为篇幅有限就不再介绍了。

GitHub: github.com/HyejeanMOON…

4. 其他教程

Google的MergeAdapter的使用
Paging在Android中的应用
Android WorkManager的使用 android中的Transition动画的使用