學習筆記| AS入門(三) 布局篇

在我們之前的學習過程中,總是需要和.xml布局文件接觸,那布局到底是什么呢?布局是指頁面內容該如何排布,比如控件和父容器的位置關系以及控件與控件之間的位置關系是怎樣的。其實除了最常見的LinearLayout 線性布局、RelativeLayout 絕對布局,AS還給我們提供了其他幾種,在Android 4.0之后,AS現在有七種布局,本篇將依次介紹,最后簡單介紹安卓布局幾點原則。目錄見下:

  • LinearLayout 線性布局
  • RelativeLayout 相對布局
  • FrameLayout 幀布局
  • AbsoluteLayout絕對布局
  • TableLayout 表格布局
  • GridLayout 網格布局
  • ConstraintLayout 約束布局
  • 幾點布局原則

在介紹之前,先要知道布局文件是如何創建的:

1
2

注意命名都要小寫~

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_xandroid: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布局的規整和易維護性。下圖是一個簡單的示例。

將常用的title抽取出來自立門戶

當別的布局需要這個title只需要include標簽,并設置layout屬性把對應的布局引入即可

(4)使用ViewStub標簽減少布局的嵌套層次,它和include一樣可以用來引入一個外部布局,但不同的是,ViewStub引入的布局不占用位置,在解析layout布局是節省了CPU和內存??捎胕nflate方法使之在布局中顯示出來。下圖是一個簡單的示例。

在需要的布局文件里使用ViewStub標簽,并設置android:layout屬性把對應的布局引入

注冊點擊事件,按下按鈕后顯示隱藏的內容

點擊前后效果

(5)使用merge標簽降低UI布局的嵌套層次:適用于布局根節點是FrameLayout且不設置background和padding等額外屬性;當某個布局作為子布局被其他布局include的時候可用merge當作該布局的頂節點。

布局篇就到這里,感謝大家的觀看~

>下篇預告:組件篇之Activity

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,420評論 25 708
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,535評論 0 17
  • 1. 靜靜的,是一剪八月的時光在筆下流淌,墨云點點,無語,無言,我很安靜,只是任由幾行小字如風絮語,在心里甩水袖般...
    瀲素月閱讀 500評論 24 16
  • 沒有誰是可以靠一輩子的,除了自己。所以必須學會獨立,必須學會享受孤獨和寂寞。
    惜月云煙雨閱讀 151評論 0 0
  • 漫步青春 似水流年 本文參與#漫步青春#征文活動,作者:羅時風,本人承諾,文章內容為原創,未在其他平臺發布。 ...
    不用訴離殤閱讀 114評論 0 0