Android-六大布局詳解

布局概述

為了讓組件(TextView,Button等)在不同的手機(jī)屏幕上都能運(yùn)行良好(不同手機(jī)屏幕分辨率宾舅、尺寸并不完全相同),如果讓程序手動(dòng)控制每個(gè)組件的大小、位置,則將給編程帶來(lái)巨大的困難铐望,為了解決這個(gè)問(wèn)題,Android提供了布局管理器茂附。布局管理器可以根據(jù)運(yùn)行平臺(tái)來(lái)調(diào)整組件的大小正蛙,咱們程序員要做的只是為容器選擇合適的布局管理器。

每當(dāng)Acitivity.setContentView(@LayoutRes int layoutResID)方法被調(diào)用何之,或者一個(gè)View通過(guò)LayoutInflater對(duì)象inflater出來(lái),那么相關(guān)的布局文件就會(huì)被加載并解析出來(lái)咽筋。XML文件中每個(gè)大寫(xiě)的XML節(jié)點(diǎn)對(duì)應(yīng)著一個(gè)View對(duì)象溶推,他們被系統(tǒng)實(shí)例化。在Acitviity或者Fragment的整個(gè)生命周期中奸攻,他們都是UI層級(jí)的一部分蒜危。這會(huì)影響到應(yīng)用程序使用過(guò)程中的分配。

Android的布局管理器本身就是個(gè)UI組件睹耐,所有的布局管理器都是ViewGroup的子類(lèi)辐赞,而ViewGroup是View的子類(lèi),所以布局管理器可以當(dāng)成普通的UI組件使用硝训,也可以作為容器類(lèi)使用响委,可以調(diào)用多個(gè)重載addView()向布局管理器中添加組件,并且布局管理器可以互相嵌套窖梁,當(dāng)然不推薦過(guò)多的嵌套(如果要兼容低端機(jī)型赘风,最好不要超過(guò)5層)。

布局層級(jí)管理

讓咱們一起了解一下每當(dāng)系統(tǒng)繪制一個(gè)布局時(shí)纵刘,都會(huì)發(fā)生一些什么邀窃。這一過(guò)程由兩個(gè)步驟完成:

1、繪制(Measurement)

a假哎、根布局測(cè)量自身瞬捕。

b、根布局要求它內(nèi)部所有子組件測(cè)量自身舵抹。

c肪虎、所有自布局都需要讓它們內(nèi)部的子組件完成這樣的操作,直到遍歷完視圖層級(jí)中所有的View惧蛹。

2笋轨、擺放( Positioning)

a秆剪、當(dāng)布局中所有的View都完成了測(cè)量,根布局則開(kāi)始將它們擺放到合適的位置爵政。b仅讽、所有子布局都需要做相同的事情,直到遍歷完視圖層級(jí)中所有的View钾挟。

b洁灵、當(dāng)某個(gè)View的屬性發(fā)生變化(如:TextView內(nèi)容變化或ImageView圖像發(fā)生變化),View自身會(huì)調(diào)用View.invalidate()方法(必須從 UI 線程調(diào)用)掺出,自底向上傳播該請(qǐng)求徽千,直到根布局(根布局會(huì)計(jì)算出需要重繪的區(qū)域,進(jìn)而對(duì)整個(gè)布局層級(jí)中需要重繪的部分進(jìn)行重繪)汤锨。布局層級(jí)越復(fù)雜双抽,UI加載的速度就越慢。因此闲礼,在編寫(xiě)布局的時(shí)候牍汹,盡可能地扁平化是非常重要的。AbsoluteLayout已被棄用柬泽,咱就不多說(shuō)它了慎菲。FrameLayout和TableLayout有各自的特殊用途,LinearLayout?和RelativeLayout是可以互換的锨并,ConstraintLayout和RelativeLayout類(lèi)似露该。也就是說(shuō),在編寫(xiě)布局時(shí)第煮,可以選擇其中一種解幼,咱們可以以不同的方式來(lái)編寫(xiě)下面這個(gè)簡(jiǎn)單的布局。

LinearLayout

第一種方式是使用LinearLayout包警,雖然可讀性比較強(qiáng)书幕,但是性能比較差。由于嵌套LinearLayout會(huì)加深視圖層級(jí)揽趾,每次擺放子組件時(shí)台汇,相對(duì)需要消耗更多的計(jì)算。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? android:orientation="vertical">

? ? <View

? ? ? ? android:id="@+id/view_top_1"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/color_666666"/>

? ? <View

? ? ? ? android:id="@+id/view_top_2"

? ? ? ? android:layout_width="200dp"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/teal_200"/>

? ? <LinearLayout

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:orientation="horizontal">

? ? ? ? <View

? ? ? ? ? ? android:id="@+id/view_top_3"

? ? ? ? ? ? android:layout_width="100dp"

? ? ? ? ? ? android:layout_height="100dp"

? ? ? ? ? ? android:background="@color/color_FF773D"/>

? ? ? ? <View

? ? ? ? ? ? android:id="@+id/view_top_4"

? ? ? ? ? ? android:layout_width="100dp"

? ? ? ? ? ? android:layout_height="100dp"

? ? ? ? ? ? android:background="@color/purple_500"/>

? ? </LinearLayout>

</LinearLayout>

LinearLayout視圖層級(jí)如下所示:

LinearLayout視圖層級(jí)

第二種方法基于RelativeLayout篱瞎,在這種情況下苟呐,你不需要嵌套其他ViewGroup,因?yàn)槊總€(gè)子View可以相當(dāng)于其他View,或相對(duì)與父控件進(jìn)行擺放俐筋。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent">

? ? <View

? ? ? ? android:id="@+id/view_top_1"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/color_666666"/>

? ? <View

? ? ? ? android:id="@+id/view_top_2"

? ? ? ? android:layout_width="200dp"

? ? ? ? android:layout_below="@id/view_top_1"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/teal_200"/>

? ? <View

? ? ? ? android:id="@+id/view_top_3"

? ? ? ? android:layout_width="100dp"

? ? ? ? android:layout_below="@id/view_top_2"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/color_FF773D"/>

? ? <View

? ? ? ? android:id="@+id/view_top_4"

? ? ? ? android:layout_width="100dp"

? ? ? ? android:layout_below="@id/view_top_2"

? ? ? ? android:layout_toRightOf="@id/view_top_3"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/purple_500"/>

</RelativeLayout>

RelativeLayout視圖層級(jí)如下所示:

RelativeLayout視圖層級(jí)

通過(guò)兩種方式牵素,可以很容易看出,第一種方式LinearLayout需要3個(gè)視圖層級(jí)和6個(gè)View澄者,第二種方式RelativeLayout僅需要2個(gè)視圖層級(jí)和5個(gè)View笆呆。

當(dāng)然请琳,雖然RelativeLayout效率更高,但不是所有情況都能通過(guò)相對(duì)布局的方式來(lái)完成控件擺放赠幕。所以通常情況下俄精,這兩種方式需要配合使用。

注意:為了保證應(yīng)用程序的性能榕堰,在創(chuàng)建布局時(shí)竖慧,需要盡量避免重繪,布局層級(jí)應(yīng)盡可能地扁平化逆屡,這樣當(dāng)View被重繪時(shí)圾旨,可以減少系統(tǒng)花費(fèi)的時(shí)間。在條件允許的情況下魏蔗,盡量的使用RelativeLayout和ConstraintLayout,而非LinearLayout砍的,或者用GridLayoutl來(lái)替換LinearLayout。

開(kāi)發(fā)者最常使用的是ViewGroup是LinearLayout,只是因?yàn)樗苋菀卓炊褐危帉?xiě)起來(lái)簡(jiǎn)單廓鞠,所以它就成了Android開(kāi)發(fā)新手的首選。出于這個(gè)原因产雹,Google推出了一個(gè)全新的ViewGroup诫惭。在適當(dāng)?shù)臅r(shí)候時(shí)候使用它翁锡,可以減少冗余蔓挖。它就是網(wǎng)格布局GridLayout下面文章中也有講到。

布局復(fù)用

Android SDK提供了一個(gè)非常有用的標(biāo)簽馆衔。在某些情況下瘟判,當(dāng)你希望在其他布局中用一些已存在的布局時(shí),<include/>標(biāo)簽可通過(guò)制定相關(guān)引用ID角溃,將一個(gè)布局添加到另一個(gè)布局拷获。比如自定義一個(gè)標(biāo)題欄,那么可以按照下面的方式减细,創(chuàng)建一個(gè)可重復(fù)用的布局文件匆瓜。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="wrap_content">

? ? <View

? ? ? ? android:id="@+id/view_top_1"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/color_666666"/>

</RelativeLayout>

接著,將<include/>標(biāo)簽放入相應(yīng)的布局文件中未蝌,替換掉對(duì)應(yīng)的View:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent">

? ? <include layout="@layout/include_layout"/>

? ? <View

? ? ? ? android:id="@+id/view_top_2"

? ? ? ? android:layout_width="200dp"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/teal_200"/>

? ? <View

? ? ? ? android:id="@+id/view_top_3"

? ? ? ? android:layout_width="100dp"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/color_FF773D"/>

</RelativeLayout>

這么一來(lái)驮吱,當(dāng)你希望重用某些View時(shí),就不用復(fù)制/粘貼的方式來(lái)實(shí)現(xiàn)萧吠,只需要定義一個(gè)layout文件左冬,然后通過(guò)<include/>引用即可。但是這樣做纸型,可能會(huì)引入一個(gè)冗余的ViewGroup(重用的布局文件的根視圖)拇砰。

為此梅忌,Android SDK提供了另一個(gè)標(biāo)簽,用來(lái)幫我們減少布局冗余除破,讓層級(jí)變得更加扁平化牧氮。我們只需要將可重用的根視圖,替換為<merge/>標(biāo)簽即可皂岔。如下所示:

<?xml version="1.0" encoding="utf-8"?>

<merge xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="wrap_content">

? ? <View

? ? ? ? android:id="@+id/view_top_1"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="100dp"

? ? ? ? android:background="@color/color_666666"/>

</merge>

如此一來(lái)蹋笼,就沒(méi)有了冗余的視圖控件,因?yàn)橄到y(tǒng)會(huì)忽略<merge/>標(biāo)簽躁垛,并將<merge/>標(biāo)簽中的視圖直接放置在相應(yīng)的布局文件中剖毯,替換<include/>標(biāo)簽。

使用此標(biāo)簽時(shí)教馆,需要記住它的兩個(gè)主要限制逊谋。

a、它只能作為布局文件的跟來(lái)使用土铺。

b胶滋、每次調(diào)用LayoutInflater.inflate()時(shí),必須為<merge/>布局文件提供一個(gè)View,作為它的父容器:

LayoutInflater.from(this).inflate(R.layout.merge_layout,parent,true);

一悲敷、線性布局(LinearLayout常用)

LinearLayout是一個(gè)視圖組究恤,呈線性橫向或縱向,依次繪制每個(gè)被添加進(jìn)來(lái)的子組件后德。

LinearLayout的所有子組件依次堆疊部宿,因此無(wú)論子視圖有多寬,垂直列表每行均只有一個(gè)子組件瓢湃,水平列表將只有一行高(最高子組件的高度加上內(nèi)邊距)理张。LinearLayout會(huì)考慮子組件之間的邊距以及每個(gè)子組件的對(duì)齊方式(右對(duì)齊、居中對(duì)齊或左對(duì)齊)绵患。

布局權(quán)重

LinearLayout還支持使用android:layout_weight屬性為各個(gè)子組件分配權(quán)重雾叭。此屬性會(huì)根據(jù)視圖應(yīng)在屏幕上占據(jù)的空間大小,向視圖分配“重要性”值落蝙。如果擁有更大的權(quán)重值织狐,視圖便可展開(kāi),填充父視圖中的任何剩余空間筏勒。子組件可指定權(quán)重值移迫,然后系統(tǒng)會(huì)按照子組件所聲明的權(quán)重值比例,為其分配視圖組中的任何剩余空間奏寨。默認(rèn)權(quán)重為零起意。

均等分布

如要?jiǎng)?chuàng)建線性布局,讓每個(gè)子組件使用大小相同的屏幕空間病瞳,請(qǐng)將每個(gè)視圖的android:layout_height設(shè)置為"0dp"(針對(duì)垂直布局)揽咕,或?qū)⒚總€(gè)視圖的android:layout_width設(shè)置為"0dp"(針對(duì)水平布局)悲酷。然后,請(qǐng)將每個(gè)視圖的android:layout_weight設(shè)置為"1"亲善。例如:

均等分布

不等分布

你也可創(chuàng)建線性布局设易,讓子元素使用大小不同的屏幕空間:

·a、如果有三個(gè)文本字段蛹头,其中兩個(gè)聲明權(quán)重為 1顿肺,另一個(gè)未賦予權(quán)重,那么沒(méi)有權(quán)重的第三個(gè)文本字段就不會(huì)展開(kāi)渣蜗,而僅占據(jù)其內(nèi)容所需的區(qū)域屠尊。另一方面,另外兩個(gè)文本字段將以同等幅度展開(kāi)耕拷,填充測(cè)量三個(gè)字段后仍剩余的空間讼昆。

·b、如果有三個(gè)文本字段骚烧,其中兩個(gè)字段聲明權(quán)重為 1浸赫,而為第三個(gè)字段賦予權(quán)重 2(而非 0),那么現(xiàn)在相當(dāng)于聲明第三個(gè)字段比另外兩個(gè)字段更為重要赃绊,因此既峡,該字段將獲得總剩余空間的一半,而其他兩個(gè)字段均享余下的空間碧查。

不等分布

二运敢、相對(duì)布局(RelativeLayout常用)

RelativeLayout是一個(gè)視圖組,每個(gè)子組件位置是相對(duì)的么夫,可以相對(duì)于同一層級(jí)下其他控件者冤,也可以相對(duì)于父控件肤视。

RelativeLayout是用于設(shè)計(jì)用戶界面的非常強(qiáng)大的實(shí)用程序档痪,因?yàn)樗梢韵短滓晥D組并保持布局層次結(jié)構(gòu)平坦,從而提高性能邢滑。如果你發(fā)現(xiàn)自己使用了多個(gè)嵌套LinearLayout組腐螟,則可以將它們替換為單個(gè)RelativeLayout。

定位視圖

RelativeLayout讓子視圖指定它們相對(duì)于父視圖或彼此的位置(由 ID 指定)困后。因此乐纸,如果A組件的位置是由B組件的位置來(lái)決定,Android要求先定義B組件摇予,再定義A組件

RelativeLayout.LayoutParams

為了控制RelativeLayout布局容器中各子組件的布局分布汽绢,RelativeLayout提供了一個(gè)內(nèi)部類(lèi):RelativeLayout.LayoutParams,該類(lèi)提供了大量的XML屬性來(lái)控制RelativeLayout布局容器中子組件的布局分布侧戴。

不設(shè)置相對(duì)位置(重疊在一起)

不設(shè)置相對(duì)位置

設(shè)置相對(duì)位置宁昭,未出現(xiàn)重疊

設(shè)置相對(duì)位置

三跌宛、網(wǎng)格布局(GridLayout)

GridLayout把這個(gè)容器劃分成rows×columns個(gè)網(wǎng)格,每個(gè)網(wǎng)格可以放一個(gè)組件积仗。 除此之外疆拘,也可以設(shè)置一個(gè)組件橫跨多少列、一個(gè)組件縱跨多少行(支持跨行和跨列以及每個(gè)單元格組內(nèi)的任意對(duì)齊形式)寂曹。

GridLayout提供了setColumnCount(int)和setRowCount(int)方法來(lái)控制該網(wǎng)絡(luò)的列數(shù)和行數(shù)哎迄。

GridLayout.LayoutParams

為了控制GridLayout布局容器中各子組件的布局分布,GridLayout提供了一個(gè)內(nèi)部類(lèi):GridLayout.LayoutParams隆圆,該類(lèi)提供了大量的XML屬性來(lái)控制GridLayout布局容器中子組件的布局分布漱挚。

這樣的布局用LinearLayout也能做,但是相對(duì)麻煩一點(diǎn)渺氧,所以在適當(dāng)?shù)臅r(shí)候時(shí)候使用GridLayout就非常的有必要了棱烂。而且你可能注意到了,子View中并沒(méi)有指定android:layout_width和android:layout_height屬性阶女。這是因?yàn)檫@兩個(gè)屬性的默認(rèn)值都是LayoutPrams.WRAP_COUNTENT,而在此颊糜,我們希望使用的就是LayoutPrams.WRAP_COUNTENT,所以就沒(méi)必要指定了秃踩。GridLayout和LinaerLayout十分相似衬鱼,所以將LinaerLayout替換為GridLayout也相當(dāng)簡(jiǎn)單。

四憔杨、表格布局(TableLayout)

TableLayout繼承了LinerarLayout,因此它的本質(zhì)依然是線性布局管理器鸟赫。表格采用行、列的形式來(lái)管理UI組件消别,TableLayout并不需要明確地聲明包含多少行抛蚤、多少列,而是通過(guò)TableRow寻狂、其他組件來(lái)控制表格的行數(shù)和列數(shù)岁经。

每次向TableLayout中添加TableRow,該TableRow就是一個(gè)表格行蛇券,TableRow也是容器缀壤,因此它也可以不斷的添加其他組件,每添加一個(gè)子組件該表格就增加一列纠亚。

如果直接向TableLayout添加組件塘慕,那么這個(gè)組件將直接占一行。

在TableLayout中蒂胞、列的寬度由該列最寬的那個(gè)單元格決定图呢,整個(gè)TableLayout的寬度取決于父容器的寬度(默認(rèn)占滿父容器)

在TableLayout中,可以為單元格設(shè)置的三種行為方式:

Collapsed:如果某列被設(shè)為Collapsed,那么該列所有單元格都會(huì)被隱藏蛤织。

Shrinkable:如果某列被設(shè)為Shrinkable拥娄,那么該列所有單元格的寬度可以被收縮,以保證該變革能適應(yīng)父容器的寬度瞳筏。

Stretchable:如果某列被設(shè)為Stretchable稚瘾,那么該列所有單元格的寬度可以被拉伸,以保證組件能完全填充滿表格空余空間姚炕。

TableLayout繼承了LinerarLayout摊欠,因此它完全可以支持LinerarLayout所支持的XML屬性。初次之外還支持下面的XML屬性柱宦。

TableLayout的常用XML屬性和相關(guān)方法說(shuō)明

XML屬性相關(guān)方法說(shuō)明

android:collapseColumn

ssetColumnCollapsed(int,boolean)要折疊的列的從零開(kāi)始的索引些椒。?

android:shrinkColumns

setShrinkAllColumns(boolean)要收縮的列的從零開(kāi)始的索引。?

android:stretchColumns

setStretchAllColumns(boolean)要拉伸的列的從零開(kāi)始的索引掸刊。?

TableLayout

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? android:layout_margin="10dp"

? ? android:orientation="vertical">

? ? <TableLayout

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:shrinkColumns="1"

? ? ? ? android:stretchColumns="2">

? ? ? ? <Button

? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? android:text="頂層大佬" />

? ? ? ? <TableRow>

? ? ? ? ? ? <Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:text="不變按鈕" />

? ? ? ? ? ? <Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:layout_marginLeft="10dp"

? ? ? ? ? ? ? ? android:text="收縮按鈕" />

? ? ? ? ? ? <Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:layout_marginLeft="10dp"

? ? ? ? ? ? ? ? android:text="拉伸按鈕" />

? ? ? ? </TableRow>

? ? </TableLayout>

? ? <TableLayout

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:collapseColumns="0"

? ? ? ? android:stretchColumns="2">

? ? ? ? <Button

? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? android:text="高層大佬" />

? ? ? ? <TableRow>

? ? ? ? ? ? <Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:text="隱藏按鈕" />

? ? ? ? ? ? <Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:layout_marginLeft="10dp"

? ? ? ? ? ? ? ? android:text="不變按鈕" />

? ? ? ? ? ? <Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:layout_marginLeft="10dp"

? ? ? ? ? ? ? ? android:text="拉伸按鈕" />

? ? ? ? </TableRow>

? ? </TableLayout>

</LinearLayout>

五免糕、幀布局(FrameLayout)

FrameLayout將控件以棧的形勢(shì)堆疊起來(lái),最近添加進(jìn)去的控件繪制在最頂部忧侧。FrameLayout為每個(gè)加入其中的組件創(chuàng)建一個(gè)空白的區(qū)域(稱(chēng)為一幀)石窑,每個(gè)子組件占據(jù)一幀,這些幀都會(huì)根據(jù)gravity屬性執(zhí)行自動(dòng)對(duì)齊蚓炬。

FrameLayout包含的子元素也受到FrameLayout.LayoutParams的控制松逊,因此它所包含的子元素也可以指定android:layout_gravity。

霓虹燈

六肯夏、約束布局(ConstraintLayout)

將該庫(kù)作為依賴項(xiàng)添加到app/ build.gradle文件中经宏,

dependencies {????implementation "androidx.constraintlayout:constraintlayout:2.0.4"????// To use constraintlayout in compose????implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha06"}

ConstraintLayout允許您以靈活的方式定位和調(diào)整子組件的大小。 它與RelativeLayout類(lèi)似驯击,所有的視圖都是根據(jù)兄弟視圖和父布局之間的關(guān)系來(lái)布局的烁兰,但是它比RelativeLayout更靈活,并且更易于在Android Studio的布局編輯器中使用徊都。

ConstraintLayout的所有功能都可以直接從布局編輯器的可視化工具中使用沪斟,因?yàn)椴季諥PI和布局編輯器是專(zhuān)門(mén)為對(duì)方構(gòu)建的。 所以你可以使用ConstraintLayout完全通過(guò)拖放操作來(lái)構(gòu)建你的布局碟贾,而不是編輯XML币喧。

請(qǐng)注意轨域,約束中不能有循環(huán)依賴袱耽。

ConstraintLayout

相對(duì)定位

相對(duì)定位是在ConstraintLayout 中創(chuàng)建布局的基本構(gòu)建塊之一。這些約束允許您相對(duì)于另一個(gè)小部件定位給定的小部件干发。您可以在水平和垂直軸上約束小部件:

水平軸:左朱巨、右、起點(diǎn)和終點(diǎn)

垂直軸:頂邊枉长、底邊和文本基線

一般概念是將小部件的給定一側(cè)約束到任何其他小部件的另一側(cè)冀续。

以下是可用約束的列表:

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

邊距

如果設(shè)置了邊距琼讽,它們將應(yīng)用于相應(yīng)的約束(如果存在),將邊距強(qiáng)制為目標(biāo)邊和源邊之間的空間洪唐。通常的布局邊距屬性可用于此效果:

android:layout_marginStart

android:layout_marginEnd

android:layout_marginLeft

android:layout_marginTop

android:layout_marginRight

android:layout_marginBottom

請(qǐng)注意钻蹬,邊距只能為正數(shù)或等于零,并且需要一個(gè)Dimension.

連接到GONE 小部件時(shí)的邊距

當(dāng)位置約束目標(biāo)的可見(jiàn)性為時(shí)View.GONE凭需,您還可以使用以下屬性指示要使用的不同邊距值:

layout_goneMarginStart

layout_goneMarginEnd

layout_goneMarginLeft

layout_goneMarginTop

layout_goneMarginRight

layout_goneMarginBottom

尺寸限制

您可以為ConstraintLayout自身定義最小和最大尺寸:

android:minWidth 設(shè)置布局的最小寬度

android:minHeight 設(shè)置布局的最小高度

android:maxWidth 設(shè)置布局的最大寬度

android:maxHeight 設(shè)置布局的最大高度

问欠、絕對(duì)布局(AbsoluteLayout)

因?yàn)殪`活性太差,在API Level 3中被廢棄粒蜈。在實(shí)際使用中你需要為所有子組件指定x,y坐標(biāo)顺献。它的直接子類(lèi)是WebView。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枯怖,一起剝皮案震驚了整個(gè)濱河市注整,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌度硝,老刑警劉巖肿轨,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蕊程,居然都是意外死亡萝招,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)存捺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)槐沼,“玉大人,你說(shuō)我怎么就攤上這事捌治「诠常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵肖油,是天一觀的道長(zhǎng)兼吓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)森枪,這世上最難降的妖魔是什么视搏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮县袱,結(jié)果婚禮上浑娜,老公的妹妹穿的比我還像新娘。我一直安慰自己式散,他們只是感情好筋遭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般漓滔。 火紅的嫁衣襯著肌膚如雪编饺。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天响驴,我揣著相機(jī)與錄音透且,去河邊找鬼。 笑死豁鲤,一個(gè)胖子當(dāng)著我的面吹牛石蔗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播畅形,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼养距,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了日熬?” 一聲冷哼從身側(cè)響起棍厌,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竖席,沒(méi)想到半個(gè)月后耘纱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡毕荐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年束析,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憎亚。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡员寇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出第美,到底是詐尸還是另有隱情蝶锋,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布什往,位于F島的核電站扳缕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏别威。R本人自食惡果不足惜躯舔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望省古。 院中可真熱鬧粥庄,春花似錦、人聲如沸衫樊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)科侈。三九已至载佳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臀栈,已是汗流浹背蔫慧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留权薯,地道東北人姑躲。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盟蚣,于是被迫代替她去往敵國(guó)和親黍析。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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