在我們之前的學習過程中,總是需要和.xml佈局檔案接觸,那佈局到底是什麼呢?佈局是指頁面內容該如何排布,比如控制元件和父容器的位置關係以及控制元件與控制元件之間的位置關係是怎樣的。其實除了最常見的LinearLayout 線性佈局、RelativeLayout 絕對佈局,AS還給我們提供了其他幾種,在Android 4.0之後,AS現在有七種佈局,本篇將依次介紹,最後簡單介紹安卓佈局幾點原則。目錄見下:
- LinearLayout 線性佈局
- RelativeLayout 相對佈局
- FrameLayout 幀佈局
- AbsoluteLayout絕對佈局
- TableLayout 表格佈局
- GridLayout 網格佈局
- ConstraintLayout 約束佈局
- 幾點佈局原則
在介紹之前,先要知道佈局檔案是如何建立的:
注意命名都要小寫~
1.LinearLayout線性佈局
線性佈局是指子控制元件以水平或垂直方式排列。先看這樣的一個線性佈局:
從圖中可以直觀的看出,這個線性佈局中的三個button是垂直排列的的,決定子控制元件的排布方向的屬性就是android:orientation,它有兩個選項,vertical表示垂直排列,horizontal表示水平排列,注意這個屬性是在這整個LinearLayout標籤之下的,是全域性屬性。
另外,佈局和佈局之間是可以巢狀的,比如下圖中展示的線性佈局中又巢狀一個線性佈局,外線性佈局的orientation使得內線性佈局和三個button以vertical方式排布,內線性佈局的orientation使得它自己的三個button以horizonal方式排布。
再介紹一組很重要的屬性:
android:gravity(表示這個容器裡所有子類控制元件的統一排布方式,有以下幾個常用個選值,center水平和垂直方向均居中、center_vertical垂直居中、center_horizontal水平居中、right最右、left最左、bottom最下,可用符號 | 實現多級連用,如android:gravity=“bottom|right")
android:layout_gravity(表示這個子控制元件相對於父容器的位置。可選值和gravity相同,也可多級聯用。當然這些選值使得子控制元件是在它父容器裡可獲得的空間裡進行的,如果這個控制元件周圍還有別的控制元件可能會影響子控制元件的位置)
這兩個屬性很容易混淆,直觀來看它們的差別是針對的物件不同。gravity是對它所有直接的子類的一個統一排布,子類的子類位置需要子類去統一排布,比如一個學校要上課間操,學校要求所有的學生以班級為單位都到操場的東南角活動,至於這個班級裡所有學生是不是在班級活動區域的東南角學校管不著,班級要求全班同學那才可以。那如果這個班某個同學是體委,不和大家都去東南角活動,而是在西南角管理班級呢?這時要對體委用layout_gravity屬性,layout_gravity針對的物件是使用這個屬性的控制元件,控制這個控制元件相對於直接父容器的位置。那麼下面這四行程式碼之後的button1位置是不是就很好理解了?
最後再介紹一個區域性屬性 android:layout_weight,是指子類控制元件佔當前父容器的比例,比如下圖顯示的button4佔兩份,button5和button6各佔一份,那麼它們的高之比就是2:1:1,但注意成立的條件是它們的高選值是wrap_content,如果是match_parent,那就成反比了。
2.RelativeLayout相對佈局
相對佈局是子控制元件以控制元件之間的相對位置或子類控制元件相對於父容器的位置排列。所以每個子控制元件可以通過兩種參考系來決定自己的位置。
一種是相對於父容器,相關的屬性有:
android:layout_alignParentBottom(在父容器最下,true或false)、
android:layout_alignParentTop(在父容器最上) 、
android:layout_alignParentLeft(在父容器最左) 、
android:layout_alignParentRight(在父容器最右)、
android:layout_marginTop(和父容器上端的距離,單位dp)、
android:layout_marginBottom(和父容器下端的距離)、
android:layout_marginLeft(和父容器左端的距離)、
android:layout_marginRight(和父容器右端的距離)、
android:layout_margin(和父容器四周的距離)、
android:layout_centerVertical(在父類的垂直居中,true或false)、
android:layout_centerHorizontal(在父類的水平居中)、
android:layout_centerInParent(在父類的水平垂直居中)。
一種是相對於其他控制元件,相關的屬性有:
android:layout_below(位於某控制元件下方,以id標記)、
android:layout_above(位於某控制元件上方)、
android:layout_toLeftOf(位於某控制元件左方)、
android:layout_toRightOf(位於某控制元件右方)、
android:layout_alignBottom(與某控制元件底部對齊,以id標記)、
android:layout_alignTop(與某控制元件頂部對齊) 、
android:layout_alignLeft(與某控制元件左邊緣對齊) 、
android:layout_alignRight(與某控制元件右邊緣對齊)、
android:layout_alignBaseline(與某控制元件的文字內容在一條直線上)
注意相對佈局裡沒有layout_weight屬性,上面展示的第一種相對於父容器的屬性就就足夠。
現在考考自己,有沒有理解了下面這兩個button的位置關係了呢?
3.FrameLayout幀佈局
幀佈局是所有子控制元件均放在左上角且後面元素直接覆蓋在前面元素之上。兩個常用屬性:android:foreground(設定改幀佈局容器的前景影像,前景影像是永遠處於幀佈局最上面的影像,就是不會被覆蓋的圖片) android:foregroundGravity(設定前景影像顯示的位置)。為更直觀,下圖裡展示的TextView都填充了顏色,可以看出textView4在最上面。
但是幀佈局的這個性質有什麼特別的用處呢?當給每個TextView都設定layout_gravity="center"之後,設想用一些方法使它們閃現不同顏色,是不是像個霓虹燈呢?感興趣的可以好好研究幀佈局具體內容~
4.AbsoluteLayout絕對佈局
絕對佈局是子控制元件通過它x,y位置來決定其位置。即android:layout_x和android:layout_y屬性。但是絕對佈局不常見,用x和y決定的控制元件在不同大小的適配螢幕上的位置直觀上會變化,在一個螢幕上的右下角並不代表在另一個螢幕上也是右下角,適應能力差,所以AS也告訴我們不建議使用。
5.TableLayout表格佈局
表格佈局是以行列的形式管理子控制元件,每一行是一個TableRow物件或者View物件。注意列是從0計數,第一列記為0。
先來看看幾個常用的全域性屬性:
android:stretchColumns(讓第幾列填補一行中多餘的空白,如果多列一起填補,用逗號分開,如android:stretchColumns=“2,3”表示地三列和第四列一起填補空白,如果是全部列均分空白,值為*)
android:shrinkColumns(如果一行中列太多或者某列文字內容太長,會導致某列被擠出螢幕,這個屬性幫助某列收縮防止被擠)
android:collapseColumns(隱藏某列) 常用的區域性屬性有:
android:layout_column(讓該子類控制元件顯示在第幾列)
android:layout_span(讓該子類控制元件佔據幾列)
下圖是一個簡易計算器的佈局,第一行是以TextView物件為一行,後面三行是以TableRow物件為一行,然後用android:stretchColumns="*"就能很方便實現每行button都均勻的填補空白,使介面更美觀,如果用線性佈局實現這一點就要麻煩一點了。
6.GridLayout網格佈局
網格佈局是在Android 4.0以後引入的一個新的佈局,和表格佈局有點類似,但比表格佈局功能更強大一些。這有一篇 網格佈局GridLayout的那些事兒 對網格佈局有較詳細的講解,還有對錶格佈局的補充,可以當作擴充套件閱讀。
7.ConstraintLayout 約束佈局
AS2.2之後新增的約束佈局,和之前出現的集中佈局不同的是,它非常適合使用視覺化的方式來編寫介面,但並不太適合使用XML的方式來進行編寫。同樣的,這一部分推薦大家閱讀最全面的ConstraintLayout教程。
8.佈局原則:
(1)儘量多使用線性佈局和相對佈局,不用絕對佈局。
(2)在佈局層次一樣下,線性佈局比相對佈局的效能要高。
(3)使用include標籤增加UI的複用效率:可把重複使用的控制元件抽取出來放在一個xml檔案裡,並在需要它的xml檔案裡通過include標籤引用。這樣做也保證了UI佈局的規整和易維護性。下圖是一個簡單的示例。
(4)使用ViewStub標籤減少佈局的巢狀層次,它和include一樣可以用來引入一個外部佈局,但不同的是,ViewStub引入的佈局不佔用位置,在解析layout佈局是節省了CPU和記憶體。可用inflate方法使之在佈局中顯示出來。下圖是一個簡單的示例。
(5)使用merge標籤降低UI佈局的巢狀層次:適用於佈局根節點是FrameLayout且不設定background和padding等額外屬性;當某個佈局作為子佈局被其他佈局include的時候可用merge當作該佈局的頂節點。
佈局篇就到這裡,感謝大家的觀看~
>下篇預告:元件篇之Activity