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來(lái)約束在验。

  • 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ì)齊來(lái)約束組件位置。我們把上面兩個(gè)示例的ImageView換成TextView腋舌,左邊的組件約束條件不變盏触,右邊組件刪除縱向方向的約束,使用baseline來(lái)代替块饺。

  • 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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谷朝,隨后出現(xiàn)的幾起案子篮灼,更是在濱河造成了極大的恐慌,老刑警劉巖徘禁,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異髓堪,居然都是意外死亡送朱,警方通過查閱死者的電腦和手機(jī)娘荡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)驶沼,“玉大人炮沐,你說(shuō)我怎么就攤上這事』亓” “怎么了大年?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)玉雾。 經(jīng)常有香客問我翔试,道長(zhǎng),這世上最難降的妖魔是什么复旬? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任垦缅,我火速辦了婚禮,結(jié)果婚禮上驹碍,老公的妹妹穿的比我還像新娘壁涎。我一直安慰自己,他們只是感情好志秃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布怔球。 她就那樣靜靜地躺著,像睡著了一般浮还。 火紅的嫁衣襯著肌膚如雪竟坛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天碑定,我揣著相機(jī)與錄音流码,去河邊找鬼。 笑死延刘,一個(gè)胖子當(dāng)著我的面吹牛漫试,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碘赖,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼驾荣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了普泡?” 一聲冷哼從身側(cè)響起播掷,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撼班,沒想到半個(gè)月后歧匈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砰嘁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年件炉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勘究。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斟冕,死狀恐怖口糕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情磕蛇,我是刑警寧澤景描,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站秀撇,受9級(jí)特大地震影響超棺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捌袜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一说搅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虏等,春花似錦弄唧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至敦跌,卻和暖如春澄干,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柠傍。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工麸俘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惧笛。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓从媚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親患整。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拜效,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容