ConstraintLayout約束布局詳解

ConstraintLayout可以翻譯為約束布局,它是Jetpack的一部分,使用ConstraintLayout需要添加Jetpack依賴。ConstraintLayout約束布局可以無(wú)嵌套的創(chuàng)建復(fù)雜的大型布局,它與RelativeLayou 相似,其中所有的視圖均根據(jù)同級(jí)視圖與父布局之間的關(guān)系進(jìn)行布局,但其靈活性要高于 RelativeLayout,并且更易于與 Android Studio 的布局編輯器配合使用。

使用ConstraintLayout

我們創(chuàng)建一個(gè)新的Android項(xiàng)目,MainActivity默認(rèn)使用的就是ConstraintLayout,新項(xiàng)目已經(jīng)添加了ConstraintLayout依賴,我們直接在布局中使用即可。

如果需要手動(dòng)添加依賴,則需要做下面兩步操作:

  1. 在項(xiàng)目根目錄的build.gradle文件中添加以下代碼:
allprojects {
     repositories {
         google()
     }
}
  1. 在app目錄下的build.gradle文件中添加以下代碼:
dependencies {
     implementation "androidx.constraintlayout:constraintlayout:2.0.4"
     // To use constraintlayout in compose
     implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-rc01"
    }

上面第一步是添加Jetpack的依賴,第二步添加的才是ConstraintLayout,后面就可以直接使用了。

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

</androidx.constraintlayout.widget.ConstraintLayout>

因?yàn)闆]有子組件,所以布局里面一片空白,下面我們了解一下ConstraintLayout的常用屬性。

約束于父容器

和RelativeLayout一樣,ConstraintLayout可以相對(duì)于父容器定位,也可以相對(duì)于兄弟組件定位。

  • app:layout_constraintBottom_toBottomOf="parent" :底部約束于父組件

  • app:layout_constraintEnd_toEndOf="parent" :右側(cè)約束于父組件

  • app:layout_constraintStart_toStartOf="parent" :左側(cè)約束于父組件

  • app:layout_constraintTop_toTopOf="parent" :頂部約束于父組件

<?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"
     tools:context=".MainActivity">
     <TextView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="ConstraintLayout約束布局"
     android:textSize="18sp"
     android:textColor="@color/black"
     app:layout_constraintBottom_toBottomOf="parent"
     app:layout_constraintEnd_toEndOf="parent"
     app:layout_constraintStart_toStartOf="parent"
     app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

效果預(yù)覽圖:

TextView居中

上面的示例中間是一個(gè)完全居中的TextView,它四邊距離父容器邊緣都是0dp,如果需要設(shè)置組件到父容器某邊的距離或者刪除某邊的依賴,可以通過操作Attributes視圖實(shí)現(xiàn),而不再操作xml文件。

attributes屬性

其它約束條件

子組件除了約束于父容器,還可以添加其它條件的約束,比如兄弟組件之間的約束,引導(dǎo)線約束,基線對(duì)齊等。

和上面約束于父容器的屬性一樣,約束于兄弟組件也用到以上屬性,只不過把parent改為兄弟組件的id而已。

  • app:layout_constraintEnd_toStartOf="@+id/center" :右側(cè)約束于id為center組件的左側(cè)

  • app:layout_constraintStart_toEndOf="@+id/center" :左側(cè)約束于id為center組件的右側(cè)

  • app:layout_constraintHorizontal_bias="0.5" :水平兩個(gè)約束之間空隙占比為0.5,即水平居中

比較的抽象,還是得從代碼和圖片上發(fā)現(xiàn)規(guī)律:

<?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"
 tools:context=".MainActivity">
 <ImageView
 android:id="@+id/center"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:src="@mipmap/ic_launcher"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintHorizontal_bias="0.5"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />
 <ImageView
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:src="@mipmap/ic_launcher"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toStartOf="@+id/center"
 app:layout_constraintHorizontal_bias="0.5"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />
 <ImageView
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:src="@mipmap/ic_launcher"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintHorizontal_bias="0.5"
 app:layout_constraintStart_toEndOf="@+id/center"
 app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

效果預(yù)覽圖:

ImageView

上圖示例中三個(gè)ImageView組件同在一排,而且都是在居中位置。左右兩個(gè)受到中間的約束,如果不想要中間的組件,但要保持左右兩個(gè)組件的相對(duì)位置不變,可以使用引導(dǎo)線Guidelines來約束。

  • app:layout_constraintGuide_percent="0.5" :引導(dǎo)線兩邊空隙占的比例
<androidx.constraintlayout.widget.Guideline
 android:id="@+id/center"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintGuide_percent="0.5"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />
guidelines

對(duì)于文本而言,還可以使用基線baseline對(duì)齊來約束組件位置。我們把上面兩個(gè)示例的ImageView換成TextView,左邊的組件約束條件不變,右邊組件刪除縱向方向的約束,使用baseline來代替。

  • app:layout_constraintBaseline_toBaselineOf="@+id/textView" : 組件的baseline約束于id為textview組件的baseline
<?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"
 tools:context=".MainActivity">
 <TextView
 android:id="@+id/textView"
 android:layout_width="wrap_content"
 android:layout_height="40dp"
 android:text="this is TextView1"
 android:textColor="@color/black"
 android:textSize="18sp"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toStartOf="@+id/center"
 app:layout_constraintHorizontal_bias="0.5"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />
 <TextView
 android:layout_width="wrap_content"
 android:layout_height="40dp"
 android:text="this is TextView2"
 android:textColor="@color/black"
 android:textSize="18sp"
 app:layout_constraintBaseline_toBaselineOf="@+id/textView"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintStart_toEndOf="@+id/center" />
 <androidx.constraintlayout.widget.Guideline
 android:id="@+id/center"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintGuide_percent="0.5"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

效果預(yù)覽圖:

baseline

右邊的TextView縱向沒有設(shè)置約束,但依然保持縱向居中,因?yàn)槭芗s束于左邊TextView的baseline。

ConstraintLayout比較適合拖拽編寫布局,它還有許多其它特性,文字描述顯然不好表達(dá),還是建議多嘗試編寫更好了解。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容