ConstraintLayout最強(qiáng)布局解析

ConstraintLayout布局出來(lái)已經(jīng)很久了,剛出來(lái)那會(huì)兒就想嘗試一下的,結(jié)果半天都沒(méi)適應(yīng),前兩天看到一篇ConstraintLayout實(shí)戰(zhàn)的文章,看完之后發(fā)現(xiàn)這布局賊雞兒好用啊,日常開(kāi)發(fā)中的大多數(shù)布局使用它都可以完成,而且也不需要嵌套。

介紹

ConstraintLayout又稱約束布局,是谷歌在2016年開(kāi)發(fā)者大會(huì)上推出的,之后在Android Studio上成為了默認(rèn)布局,該布局能減少布局的層級(jí)嵌套,我們都知道,View嵌套的越多,在加載的過(guò)程中解析起來(lái)就越費(fèi)時(shí)間,該布局幾乎能做到LinearLayoutRelativeLayout嵌套完成的任何布局,下面跟著一波小demo來(lái)深入了解谷歌推薦的ConstraintLayout。

用法簡(jiǎn)介

1、xxx_toyyyOf屬性

xxx是當(dāng)前的控件,yyy是指定控件,這個(gè)指定控件也可以是容器本身(parent)

ConstraintLayout中有以下多種這樣的屬性:

  • 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

image

參照上圖給出的解釋,以上屬性都可以這樣用,有點(diǎn)類似RelativeLayout中的toLeftOf,toRightOf,上面的屬性中還有一個(gè)關(guān)于Baseline的,我們通過(guò)另外一張圖來(lái)了解一下:

image

Baseline是控件中文字的基準(zhǔn)線,這里可以理解為參照某個(gè)控件中的文字底部對(duì)齊,來(lái)看看樣式:

image

如果不加基準(zhǔn)線對(duì)齊的話,那么ButtonA的位置就在容器的左上角。

2、設(shè)置margin邊距

邊距,和傳統(tǒng)的布局是一樣的用法,但是這里要注意的是,必須要設(shè)置自己的相對(duì)位置(先要指定自己在容器中的位置,可以是相對(duì)容器的,也可以是相對(duì)某個(gè)控件的),如果不設(shè)置的話,那么設(shè)置margin是無(wú)效的,大家可以試試,在一個(gè)ConstraintLayout布局中放一個(gè)按鈕,除了邊距之外什么都不設(shè)置,這樣是沒(méi)有效果的,因?yàn)槟銢](méi)有在布局中給它設(shè)置相對(duì)位置。

3、隱藏空間設(shè)置邊距

ConstraintLayout中有以下多種這樣的屬性:

  • layout_goneMarginStart

  • layout_goneMarginEnd

  • layout_goneMarginLeft

  • layout_goneMarginTop

  • layout_goneMarginRight

  • layout_goneMarginBottom

平常我們?cè)陂_(kāi)發(fā)過(guò)程中會(huì)遇到這樣一個(gè)問(wèn)題,當(dāng)一個(gè)控件被設(shè)置成gone之后,與之關(guān)聯(lián)的控件的位置常常也會(huì)發(fā)生改變,來(lái)看看樣式:

image

平常我們寫(xiě)標(biāo)題欄的時(shí)候應(yīng)該都遇到過(guò)右邊放兩個(gè)按鈕的情況,而且是可以控制顯示隱藏的,當(dāng)最右邊的按鈕隱藏之后,左邊的按鈕也要距離右邊有一個(gè)邊距,這種情況下我們就可以使用上面這些屬性來(lái)配置布局。

4、居中和偏移

  • 水平居中
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
image

這個(gè)很好理解,設(shè)置與容器的左邊和右邊分別對(duì)齊,這樣的話就能讓控件水平居中了,同理垂直居中和中心對(duì)齊也是這樣。可能有人會(huì)吐槽了,寫(xiě)這么多還不如我用LinearLayoutRelativeLayout寫(xiě)一句代碼來(lái)的快呢?老鐵還真是個(gè)急性子,接著往下看。

  • 垂直居中
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
  • 中心
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

下面來(lái)實(shí)現(xiàn)一個(gè)這樣的功能,讓一個(gè)控件在距離左邊和距離右邊的比例是1:3,來(lái)看看正經(jīng)寫(xiě)法:

image
<LinearLayout>

    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
        
    <Button
        android:layout_width="100dp"
        android:layout_height="match_parent" />
    
    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />

</LinearLayout>

相信大多數(shù)老鐵都會(huì)這么寫(xiě),那么我們現(xiàn)在來(lái)看看不正經(jīng)的寫(xiě)法:

<android.support.constraint.ConstraintLayout>

    <Button 
        android:id="@+id/button"
        app:layout_constraintHorizontal_bias="0.33"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent />
        
</android.support.constraint.ConstraintLayout>

看到這個(gè)是不是驚呆了,一行代碼就搞定了,簡(jiǎn)直不要太簡(jiǎn)潔。

5、CircleRadius角度定位(在版本1.1中加入)

image

官網(wǎng)給出的解釋是,你可以以角度和距離約束窗口小部件中心相對(duì)于另一個(gè)窗口小部件中心??赡苡行┤丝床惶?,我也沒(méi)看懂(哈哈,LZ你是來(lái)搞笑的嗎),但是看官網(wǎng)給出的圖我大概明白是什么意思了,簡(jiǎn)單來(lái)說(shuō)就是可以根據(jù)兩個(gè)控件的中心來(lái)形成約束關(guān)系,然后可以通過(guò)設(shè)置角度來(lái)控制這個(gè)約束關(guān)系(還看不懂的話那就來(lái)實(shí)踐一把)

image

layout_constraintCircle表示相對(duì)某一指定控件,上圖中表示相對(duì)ButtonA;layout_constraintCircleRadius表示該控件的中心點(diǎn)到指定控件的中心點(diǎn)的距離(兩點(diǎn)之間,直線最短);layout_constraintCircleAngle表示該控件的中心點(diǎn)在指定控件垂直方向上的角度(范圍是0-360),具體看上圖中標(biāo)示的。

6、尺寸約束

ConstraintLayout布局中,你可以設(shè)置布局的最大和最小尺寸,而且你可通過(guò)三種方式來(lái)設(shè)置控件的大小:

  • 特定數(shù)值,比如123dp

  • 使用wrap_content,控件將自己計(jì)算大小

  • 使用0dp,相當(dāng)于MATCH_CONSTRAINT

注意:match_parent官方不建議在ConstraintLayout布局中使用,可以通過(guò)設(shè)置MATCH_CONSTRAINT(真實(shí)數(shù)值是0dp)配合約束來(lái)定義布局

下面我們來(lái)看一個(gè)例子:

image

ButtonA是固定寬度且靠左,給ButtonB設(shè)置了約束,剛開(kāi)始預(yù)期的是設(shè)置ButtonB的寬度慢慢增大,超過(guò)ButtonA之后不管設(shè)置多大都像ButtonCButtonD一樣,但是ButtonA卻把ButtonB覆蓋了,顯然這不是我們需要的,這時(shí)候MATCH_CONSTRAINT的作用就能體現(xiàn)出來(lái)了,怎么理解這個(gè)MATCH_CONSTRAINT,我們可以理解成為了配合約束布局而代替了match_parent

7、設(shè)置寬高比例

在使用百分比布局時(shí),有兩種形式可以設(shè)置:

  • layout_constraintDimensionRatio,給寬或者高其中一個(gè)設(shè)置為0dp,然后設(shè)置該屬性是一個(gè)比例,寬和高的比(相對(duì)那個(gè)已知長(zhǎng)度的),可能說(shuō)的有點(diǎn)繞,下面我們直接看demo:
image
  • app:layout_constraintDimensionRatio,設(shè)置寬和高都為0dp,然后設(shè)置改屬性的值為H,x:y 或者 W,x:y,看一下demo
image

8、Chains(鏈)

鏈條在同一方向上(水平或者垂直)為一組互相關(guān)聯(lián)的控件作統(tǒng)一管理,并且鏈由鏈頭(鏈的第一個(gè)元素)設(shè)置的屬性控制,鏈頭是水平鏈的最左側(cè)的元素,是垂直鏈的最頂部的元素。我們來(lái)看看一些鏈的樣式:

image

我們只需要設(shè)置layout_constraintHorizontal_chainStyle或者layout_constraintVertical_chainStyle的屬性就好了,而這個(gè)屬性有以下幾種配置:

  • CHAIN_SPREAD模式:元素將展開(kāi)(默認(rèn)樣式)

  • 加權(quán)鏈CHAIN_SPREAD模式:如果給元素的寬或者高設(shè)置了MATCH_CONSTRAINT(0dp),它們將分割寬高方向上的可用空間

  • CHAIN_SPREAD_INSIDE模式:類似于SPREAD,但鏈的端點(diǎn)不會(huì)分散

  • CHAIN_PACKED模式:鏈條的元素將被捆綁在一起。然后,子項(xiàng)的水平或垂直偏差屬性將影響該鏈元素的定位

9、輔助布局Guildline

這是ConstraintLayout布局特有的功能,你可以用它來(lái)輔助你完成布局,類似于高中數(shù)學(xué)圖形學(xué)中的輔助線,只不過(guò)這條輔助線只有兩個(gè)方向,水平和垂直:

  • 當(dāng)設(shè)置線的方向?yàn)?code>horizontal時(shí),輔助線的高度為0,寬度是容器的寬度。

  • 當(dāng)設(shè)置線的方向?yàn)?code>vertical時(shí),輔助線的寬度為0,高度時(shí)容器的高度。

我們來(lái)看看Guildline的樣式(需要注意的是,輔助線是不可見(jiàn)的,只有在預(yù)覽的時(shí)候才能通過(guò)鼠標(biāo)選中可見(jiàn)):

image

Guildline有三個(gè)常用的屬性,用來(lái)控制輔助線的位置:

  • layout_constraintGuide_begin:指定輔助線距離左邊或者頂部的距離

  • layout_constraintGuide_end:指定輔助線距離右邊或者底部的距離

  • layout_constraintGuide_percent:指定在父控件中的寬度或高度的百分比

代碼

以上demo的代碼全都上傳至ConstraintLayout最強(qiáng)布局解析,有興趣的童鞋可以自行下載看看

參考

官網(wǎng)ConstraintLayout講解

泓洋_ConstraintLayout 完全解析

實(shí)戰(zhàn)篇ConstraintLayout的崛起之路

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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