約束布局ConstraintLayout基礎使用

前言

約束布局ConstraintLayout作為Google官方推薦的layout布局文件黑界,是一個和線性布局LinearLayout馍刮,相對布局Relativelayout相似的ViewGroup己莺。
約束布局的出現(xiàn)主要是為了能夠讓布局的設計更加的扁平化,優(yōu)化布局嵌套問題,能夠更加靈活的調整和控制其中的子View隆敢。

約束布局支持API 9以上的Android系統(tǒng)上使用驯耻。

一亲族、包引入

使用ConstraintLayout需要引入對應的包,在build.gradle文件中引入如下內容:

    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

二可缚、基本使用

約束布局已經支持非常多的功能孽水,主要包括如下幾個部分:

  1. 相對定位
  2. 角度定位
  3. 可見性行為
  4. 尺寸限制
  5. 鏈條
  6. 虛擬化助手對象
  7. 優(yōu)化器

下面我們將會對上述內容進行逐一講解。

1. 相對定位

相對定位是用來控制子View在ConstraintLayout內部的位置關系城看,它類似于相對布局相對布局Relativelayout女气,能夠以一個View為起點,逐步的定位其他子View的相對位置關系测柠,它包含的主要設置屬性主要包括上下左右四個方面炼鞠,屬性名稱如下:

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_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf

這塊屬性上大家可能容易搞亂,可以簡單認為前一個方向是當前子View的方向邊緣轰胁,后一個方向是參照View的方向邊緣谒主,以layout_constraintBottom_toTopOf為例,你設置的是當前View的底部(bottom)在參照View的頂部(top)赃阀。

上面屬性上包括一個layout_constraintBaseline_toBaselineOf,這個指的是中心基準線霎肯,可以使得兩個并排的View的中心基準線在同一水平上,基準線如下圖:

相對定位1.jpg
居中定位

如果當你設置的當前控件起始點分別參照兩個View而你當前的控件大小不能夠完全填充兩個參考控件間距大小的情況下,當前設置的控件會被參考View雙向拉伸的效果观游,從而使你當前的控件有居中效果搂捧,示例如下:
我們設置當前button的left和right指向parent,

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

實際效果如下:

居中定位1.jpg
偏向定位

如果需要實現(xiàn)偏向效果懂缕,讓當前的控件不再居中而是更加偏向左右 允跑,可以通過額外定義bias屬性來實現(xiàn)。這一屬性用來設置左側和上方的百分比數(shù)值搪柑,數(shù)值越小聋丝,則當前控件會更加靠近左側或者上方,如果不設置居中的情況下默認是0.5工碾。

bias能使約束偏向某一邊弱睦,默認是0.5
layout_constraintVertical_bias //縱向(0:最上,1:最下)
layout_constraintHorizontal_bias//橫向(0:最左渊额,1:最右)

舉例來說每篷,如果我們想要更加偏向左側
30%,我們就可以設置

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.3"

效果如下:

偏壓.png

2. 角度定位

除了上述的基本相對定位之外端圈,約束布局還支持角度相對定位焦读,具體方向是以Y軸正半軸為旋轉起始線,順時針旋轉計算角度舱权,示例圖如下:


角度定位.png

其中角度定位的主要參數(shù)主要包括三項:定位原點View矗晃,旋轉角度,距離宴倍,分別通過下面三項進行處理:

<!--定位原點View-->
app:layout_constraintCircle="@id/tv_testA"
<!--旋轉角度-->
app:layout_constraintCircleAngle="120"
<!--距離-->
app:layout_constraintCircleRadius="120dp"

3. 可見性行為

當約束布局設置為Gone隱藏當前的控件時张症,當前的控件被解析成一個點,對于其他的控件的約束依然存在鸵贬,但是被隱藏的View本身設置margin會被忽略俗他,具體示例如下:

可見性行為.png

當View A被設置為不可見時,其對于View B的約束依然存在阔逼,但是View A本身的左邊距會同時也隱藏掉兆衅。

goneMargin

當位置約束目標的可見性為View.GONE時,可以使用goneMargin屬性設置不同的邊距值嗜浮。
如上圖羡亩,如果設置View B的app:layout_goneMarginLeft="10dp",則當View A設置為View.GONE時,View B距離左側邊距則為10dp危融。

4. 尺寸限制

———— 大小約束
  • 當約束布局的尺寸大小設置為wrap_content時畏铆,可以設置其最大大小和最小大小,設置參數(shù)如下:
android:minWidth 設置布局的最小寬度
android:minHeight 設置布局的最小高度
android:maxWidth 設置布局的最大寬度
android:maxHeight 設置布局的最大高度
  • 使用0dp吉殃,等同** MATCH_CONSTRAINT**辞居,默認行為是使得結果尺寸占用所有的可用空間楷怒,可替代match_parent
百分比維度

尺寸設置為MATCH_CONSTRAINT時可以采用百分比設置瓦灶,屬性如下:

app:layout_constraintWidth_default="percent"
app:layout_constraintHeight_default="percent"

然后將layout_constraintWidth_percentlayout_constraintHeight_percent屬性設置為 0 到 1 之間的值用來制定當前控件的百分比鸠删。

示例如下,我們設置當前控件的寬度百分比為0.33倚搬,高度百分比為0.5,代碼如下:

<?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=".constraintlayout.TestConstraintLayoutActivity">

    <TextView
        android:id="@+id/tv_testA"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/black"
        android:padding="10dp"
        android:text="test text"
        app:layout_constraintVertical_bias="0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.33" />


</androidx.constraintlayout.widget.ConstraintLayout>

效果如下:


約束布局百分比.jpg
寬高比設置

當寬或者高至少一個尺寸設置為0dp時乾蛤,可以通過屬性app:layout_constraintDimensionRatio="m:n"來設置當前控件的寬高比.
屬性默認中m為寬度每界,n為高度。你也可以指定m的為高度或者寬度家卖,需要在添加H或者W眨层。如:

app:layout_constraintDimensionRatio="H,2:3"指的是 高:寬=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 寬:高=2:3

示例效果如下:

<?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=".constraintlayout.TestConstraintLayoutActivity">

    <TextView
        android:id="@+id/tv_testA"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/black"
        android:padding="10dp"
        android:layout_marginTop="@dimen/dp_52"
        android:text="test text"
        app:layout_constraintDimensionRatio="1:2"
        app:layout_constraintVertical_bias="0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>
寬高比.jpg

三、鏈條

鏈條也是約束布局里的一個組行為用法上荡,可以在一個軸上對鏈條組做操作趴樱。
如下圖:

鏈條.jpg

當一組部件通過雙向連接連在一起,則他們可以被視為一條鏈酪捡,其中第一個元素被稱為鏈頭叁征。代碼如下:

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/TextView2" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/TextView1"
        app:layout_constraintRight_toLeftOf="@+id/TextView3"
        app:layout_constraintRight_toRightOf="parent" />

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/TextView2"
        app:layout_constraintRight_toRightOf="parent" />

設置好鏈頭之后,我們可以在鏈頭的地方添加屬性已調整整個鏈條的樣式逛薇,一共有三種樣式:

  • CHAIN_SPREAD-- 元素將被展開(默認樣式)

加權鏈 - 在CHAIN_SPREAD模式下捺疼,如果某些小部件設置為MATCH_CONSTRAINT,它們將分割可用空間永罚,使用layout_constraintHorizontal_weightlayout_constraintVertical_weight來分別控制每個元素的權重啤呼。

  • CHAIN_SPREAD_INSIDE-- 類似,但鏈的端點不會散開
  • CHAIN_PACKED-- 鏈的元素將被打包在一起呢袱。子元素的水平或垂直偏差屬性將影響打包元素的定位

示例效果如下:


鏈條樣式.jpg

三官扣、輔助工具

1. Barrier

Barrier可以為我們設置一道分界線線以便我們調整布局。
例如我們有3個控件羞福,其中testB在testA的下方惕蹄,testC在A和B的右方,如果此時A和B的長度不是固定的治专,則此時C的約束依賴無論是A還是B都不正確焊唬,有可能造成遮擋。

barrier1.jpg

使用Barrier可以解決這一問題看靠。Barrier可以生成一道以A和B的右側為基準的分界線赶促,這樣C約束依賴于這道分界線即可,示例代碼如下:

<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=".constraintlayout.TestConstraintLayoutActivity">

    <TextView
        android:id="@+id/tv_testA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/dp_52"
        android:background="@color/colorAccent"
        android:padding="10dp"
        android:text="testA"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_testB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/dp_52"
        android:background="@color/colorAccent"
        android:paddingHorizontal="@dimen/dp_30"
        android:paddingVertical="@dimen/dp_10"
        android:text="testB"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_testA" />

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="right"
        app:constraint_referenced_ids="tv_testA,tv_testB" />

    <TextView
        android:id="@+id/tv_testC"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/dp_20"
        android:layout_marginTop="@dimen/dp_24"
        android:background="@color/colorAccent"
        android:padding="10dp"
        android:text="testC"
        app:layout_constraintLeft_toRightOf="@id/barrier1"
        app:layout_constraintTop_toTopOf="@id/tv_testA" />

</androidx.constraintlayout.widget.ConstraintLayout>

app:barrierDirection為屏障所在的位置,可以分別設置上下左右等方向挟炬。
app:constraint_referenced_ids為屏障引用的控件鸥滨,可設置多個(用“,”隔開)

效果:


barrier2.jpg

分界線并不會真實顯示嗦哆,只用來做約束依賴。

2. Group

Group可以把多個控件歸為一組婿滓,方便對當前組的控件統(tǒng)計的進行隱藏或者顯示老速,其用法和barrrier相似,都是設置constraint_referenced_ids屬性凸主,示例如下,把tv_testAtv_testB一起隱藏:

    <androidx.constraintlayout.widget.Group
        android:visibility="gone"
        app:constraint_referenced_ids="tv_testB,tv_testA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

參考文檔

約束布局的官方文檔

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末橘券,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子卿吐,更是在濱河造成了極大的恐慌旁舰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗡官,死亡現(xiàn)場離奇詭異箭窜,居然都是意外死亡,警方通過查閱死者的電腦和手機衍腥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門磺樱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人婆咸,你說我怎么就攤上這事竹捉。” “怎么了尚骄?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵活孩,是天一觀的道長。 經常有香客問我乖仇,道長憾儒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任乃沙,我火速辦了婚禮起趾,結果婚禮上,老公的妹妹穿的比我還像新娘警儒。我一直安慰自己训裆,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布蜀铲。 她就那樣靜靜地躺著边琉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪记劝。 梳的紋絲不亂的頭發(fā)上变姨,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音厌丑,去河邊找鬼定欧。 笑死渔呵,一個胖子當著我的面吹牛,可吹牛的內容都是我干的砍鸠。 我是一名探鬼主播扩氢,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼爷辱!你這毒婦竟也來了录豺?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤饭弓,失蹤者是張志新(化名)和其女友劉穎双饥,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體示启,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡兢哭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年领舰,在試婚紗的時候發(fā)現(xiàn)自己被綠了夫嗓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡冲秽,死狀恐怖舍咖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情锉桑,我是刑警寧澤排霉,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站民轴,受9級特大地震影響攻柠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜后裸,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一瑰钮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧微驶,春花似錦浪谴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扶檐,卻和暖如春凶杖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背款筑。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工官卡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蝗茁,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓寻咒,卻偏偏與公主長得像哮翘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子毛秘,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容