- Android應用開發教程(第2版)
- 羅文主編
- 2577字
- 2021-10-27 15:03:57
3.1 布局管理器

06 布局管理器
在Android中使用Android布局管理器,可以很方便和精準地控制各組件的位置和大小。Android提供了線性布局(LinearLayout)、幀布局(FrameLayou t)、表格布局(TableLayout)、相對布局(RelativeLayout)、約束布局(ConstraintLayout)、網格布局(GridLayout)、絕對布局(AbsoluteLayout)等管理器。其中,絕對布局管理器已被淘汰,不再使用;相對布局管理器和網格布局管理器也將逐漸淘汰。Google推薦使用約束布局管理器,本節為方便理解約束布局的使用,對相對布局管理器也做了介紹。在Android中,可以在XML布局文件中定義布局管理器,也可以使用Java代碼創建,Android推薦使用XML布局文件來定義布局管理器。
通過使用布局管理器,本節將實現一個橫向的計算器輸入界面,如圖3-1所示,即A+B=C的樣式,其中A、B為編輯框,+、C為文本,=為按鈕,各組件平均分布。

圖3-1 計算器界面
3.1.1 線性布局
線性布局(LinearLayout)是最常見的一種布局形式。利用線性布局的orientation屬性可以設定界面元素呈現垂直(Vertical)或水平(Horizontal)排列,每一個子元素都位于前一個元素之后。如果是垂直排列,那么將是一個N行單列的結構,每一行只會有一個元素,不論這個元素的寬度為多少,如圖3-2所示;如果是水平排列,那么將是一個單行N列的結構,并且Android的線性布局不會換行,當組件一個接著一個排列到窗體的邊緣后,剩下的組件將不會顯示出來,如圖3-3所示。

圖3-2 垂直線性布局

圖3-3 水平線性布局
在XML中定義線性布局管理器的方法與同其他資源一樣,AS支持圖形模式和代碼模式混合編輯,在XML代碼中使用<LinearLayout>標記,默認添加的線性布局代碼如下。

在線性布局管理器中,常用的屬性如表3-1所示。
表3-1 線性布局常用屬性

3.1.2 幀布局
幀布局(FrameLayout)是所有布局中最簡單的一個布局。在這個布局中,整個界面被當成一塊空白備用區域,所有的子元素都不能指定位置屬性,它們統統放于這塊區域的左上角,依據幀布局的gravity屬性執行自動對齊,并且后面的子元素直接覆蓋在前面的子元素之上,將前面的子元素部分或全部遮擋。幀布局常用屬性如表3-2所示。
表3-2 幀布局常用屬性

如下的示例在幀布局中添加三個TextView組件,第一個TextView被第二個TextView遮擋,第三個TextView遮擋了第二個TextView,代碼如下。

顯示效果如圖3-4所示。

圖3-4 幀布局示例
3.1.3 表格布局
表格布局(TableLayout)適用于N行N列的布局格式。一個TableLayout中可以添加多個<TableRow>標記,一個TableRow就代表TableLayout中的一行。TableRow也是容器,所以可以在該標記中添加其他組件,每添加一個組件,表格就會增加一列。在表格布局中,通過設置可以對列進行隱藏和伸展操作,從而填充可利用的屏幕空間,也可以設置為強制收縮,直到表格匹配屏幕大小。在TableRow中,單元格可以為空,但是不能跨列。如果直接在TableLayout中添加組件,則這個組件將獨占一行。
TableRow是LinearLayout的子類,它的android:orientation屬性值恒為horizontal,并且它的android:layout_width和android:layout_height屬性值恒為MATCH_PARENT和WRAP_CONTENT,所以它的子元素都是橫向排列并且寬高一致的。這樣的設計使得每個TableRow里的子元素都相當于表格中的單元格一樣。
TableLayout也繼承自LinearLayout,因此它支持LinearLayout的全部屬性。此外,TableLayout還支持表3-3所示的XML屬性。
表3-3 TableLayout支持的XML屬性

(續)

如下的示例使用了表格布局,在其中添加了幾個TableRow組件,代碼如下。

顯示效果如圖3-5所示。

圖3-5 表格布局示例
3.1.4 相對布局
相對布局(RelativeLayout)按照各子元素之間的相對位置關系完成布局,如某個元素在另一個組件元素的左邊、右邊、上方或下方等。在此布局中的子元素所設置的與位置相關的屬性將生效,例如android:layout_below、android:layout_above等,子元素通過這些屬性和各自的ID配合指定位置關系。注意在指定位置關系時,引用的ID必須在引用之前先被定義,否則將出現異常。相對布局常用屬性如表3-4所示。
表3-4 相對布局常用屬性

因為相對布局的最終結果還要依靠內部元素的位置屬性控制,除了以上布局管理器自身的屬性設置外,布局管理中的各組件元素還需要設置相應的XML屬性才能完成布局。相對布局中組件元素常用位置屬性如表3-5所示。
表3-5 相對布局中組件元素常用位置屬性

例如以下的布局代碼定義。


顯示效果如圖3-6所示。

圖3-6 相對布局示例
3.1.5 約束布局
約束布局(ContraintLayout)的出現是為了在Android應用布局中保持扁平的層次結構,減少布局的嵌套,為應用創建響應快速而靈敏的界面。按照Google公司官方的發展思路,約束布局將替代相對布局,并成為未來主要使用的布局方式。在相對布局中,組件的位置是按照相對位置來計算的,組件之間的位置具有相對對應的關系。而在約束布局中,組件之間、組件與父布局之間具有約束關系,組件的位置是按照約束來計算的;使用約束布局時,也可以添加引導線(Guideline)來輔助布局,所有的布局可以在布局管理器中通過拖動和調整來完成,相對于相對布局要靈活方便許多。
在約束布局中,需要理解組件前、后、上、下、左、右關系。以兩個文本框為例,其各定位關系如圖3-7所示。

圖3-7 約束布局中各定位關系
在約束布局管理中,布局屬性是放在布局所管理的控件上,一般是設置當前組件相對于其他組件或父組件的位置變化。約束布局中組件常用屬性如表3-6所示。
表3-6 約束布局中組件常用屬性

(續)

約束布局的部分屬性與相對布局中屬性的意義相同,如表3-7所示。不過,組件在約束布局里面要實現margin,必須先約束該組件在約束布局中的位置,也就是需要先定義與其他組件的約束定位關系。
表3-7 相對距離屬性

只有當約束定位所引用組件的visible屬性設置了“Gone”后,表3-8中的其他相對距離屬性才生效。
表3-8 其他相對距離屬性

如下采用相對布局實現的示例,同其他布局一樣,在約束布局中可嵌套其他布局方式,代碼如下。



顯示效果如圖3-8所示。

圖3-8 約束布局示例
如果通過如圖3-9所示的方式將兩個或以上組件約束在一起,就可以認為它們是一條鏈(圖示為橫向的約束鏈,縱向約束鏈同理)。

圖3-9 約束鏈
代碼如下。


一條鏈的第一個組件是這條鏈的鏈頭,可以在鏈頭中設置layout_constraintHorizontal_chainStyle屬性來改變整條鏈的樣式。鏈提供了3種樣式,分別是:
● CHAIN_SPREAD:展開元素(默認)。
● CHAIN_SPREAD_INSIDE:展開元素,但鏈的兩端貼近parent。
● CHAIN_PACKED:鏈的元素將被打包在一起。
三種樣式的顯示效果如圖3-10所示。

圖3-10 鏈樣式屬性設置效果
約束布局還在不斷發展更新中,一些輔助工具和新功能在不斷產生,如Optimizer、Barrier、Group、Placeholder、Guideline等,其更新的特性可參考Google官網的介紹。
3.1.6 實例1:計算輸入界面
橫向排列的效果可以使用多種布局以不同的組合方式實現,本節直接使用默認的約束布局實現。
1.新建項目,設置基本信息
在AS中新建項目,應用程序命名為“計算輸入界面”,項目命名為“ch03_01”,其他項保留默認值。
2.用線性布局實現
打開項目的res\layout\activity_main.xml布局文件,刪除其中默認添加的組件,確認其布局為約束布局,然后在線性布局中添加所需的TextView、EditText、Button等組件并設置各自的相對約束關系,最后形成的布局文件代碼如下。


