布局概述
為了讓組件(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包警,雖然可讀性比較強(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í)如下所示:
第二種方法基于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í)如下所示:
通過(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ì)位置宁昭,未出現(xiàn)重疊
三跌宛、網(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)始的索引掸刊。?
<?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)依賴袱耽。
相對(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。