2.1.2 快速掌握 Android 中的六大布局

本篇我們介紹了六大布局Linear Layout(線性布局)平委、Frame Layout(幀布局)画拾、Relative Layout(相對布局)啥繁、Absolute Layout(絕對布局)、Table Layout(表格布局)碾阁、Absolute Layout(絕對布局)的常用屬性输虱,然后結(jié)合實際開發(fā)中遇到的各種場景給出了相應(yīng)的解決方案和示例用法,并且結(jié)合不同布局的各自特點給出了自身特有的屬性(重復(fù)的屬性不會列出)脂凶,方便大家在后續(xù)學(xué)習(xí)UI排布的課程中進行查閱宪睹。最后,給出了 Android 中布局優(yōu)化的一些建議蚕钦。

什么是布局亭病?

布局是一種可用于放置很多控件的容器,它可以按照一定的規(guī)律調(diào)整內(nèi)部控件的位置嘶居,從而編寫出精美的界面罪帖。當(dāng)然了,布局的內(nèi)部除了放置控件外邮屁, 也可以放置布局整袁,通過多層布局的嵌套,我們就能夠完成一些比較復(fù)雜的界面實現(xiàn)佑吝。

Layout

為了更好地管理Android應(yīng)用的用戶界面里的個組件坐昙,Android提供了布局管理器,通過布局管理器芋忿,Android應(yīng)用的圖形用戶界面就具有了良好的平臺無關(guān)性炸客。這就讓各個控件都可以有條不紊地擺放在界面上,而不是亂糟糟的戈钢。

一痹仙、線性布局 Linear Layout

LinearLayout是一種非常常用的布局,正如它名字所描述的一樣殉了,這個布局會將它所包含的控件在線性方向上依次排列开仰,當(dāng)然肯定就不僅只有一個方向,我們可以通過 android:orientation 這個屬性指定排列方向是 vertical 還是 horizontal,控件就會在豎直方向上或者水平方向上進行排列抖所。

下面我們通過實例來體會一下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity= "right|center_vertical">
<Button
    android:id="@+id/bn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/bn1"/>
<Button
    android:id="@+id/bn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/bn2"/>
<Button
    android:id="@+id/bn3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/bn3"/>
<Button
    android:id="@+id/bn4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/bn4"/>
<Button
    android:id="@+id/bn5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/bn5"/>
</LinearLayout>

上面的布局界面很簡單梨州,只是很簡單的定義了一個線性布局,在布局中定義了五個按鈕并制定了屬性“android:gravity = "right | center_vertical"”田轧,實際運行效果如下:

LinearLayout效果一

如果將上面的屬性改為“android:gravity = "bottom | center_horizontal"”暴匠,那么實際運行效果為:

LinearLayout效果二

也就是說在垂直布局的前提下底部居中、水平居中傻粘,就變成了這個樣子每窖,可以看到屬性對局部的影響是很大的。

下面列出LinearLayout常用的屬性:

android:layout_gravity: 本元素相對于父元素的重力方向
android:layout_weight:子元素對未占用空間水平或垂直分配權(quán)重值
android:gravity[setGravity(int)] :本元素所有子元素的重力方向
android:orientation[setOrientation(int)]:線性布局以列或行來顯示內(nèi)部子元素
android:divider[setDividerDrawable(Drawable)]:設(shè)置垂直布局時兩個控件之間的分隔條
android:baselineAligned[setBaselineAligned(boolean)]:該屬性為false弦悉,將會阻止該布局管理器與它的子元素的基線對齊
android:measureWithLargestChild[setMeasureWithLargestChildEnabled(boolean)]當(dāng)該屬性設(shè)置為true時窒典,所有帶權(quán)重的子元素都會具有最大子元素的最小尺寸

問1:android:layout_gravity 和 android:gravity 有什么區(qū)別?

  • android:gravity:對元素本身起作用-本身元素顯示在什么位置
  • android:layout_gravity:相對與它的父元素-元素顯示在父元素的什么位置

如:Button控件

  • android:layout_gravity 表示button在界面上的位置
  • android:gravity 表示button上的字在button上的位置

問2:受控子元素如何設(shè)置稽莉?

LinearLayout的所有子元素都受 LinearLayout.LayoutParams 的控制瀑志,因此 Linear Layout 包含的子元素可以額外指定以下屬性:

  • android:layout_gravity 子元素在LinearLayout中的對齊方式
  • android:layout_weight 子元素在LinearLayout中所占的權(quán)重

所以我們要實現(xiàn)第一個的 1:2 的效果,只需要分別把兩個 Linear Layout 的 weight 分別設(shè)置成1和2就可以了污秆。

比如將上述布局代碼改為如下方式:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:background="#2fc1ff"
        android:layout_weight="1"/>
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:background="#f7242b"
        android:layout_weight="2"/>
</LinearLayout>
那么實際的運行效果為:
權(quán)重分配效果

用法歸納:

按比例劃分水平方向劈猪,將涉及到的 View 的 android:width 屬性設(shè)置為 0dp,然后設(shè)置為 android weight 屬性設(shè)置比例即可良拼;類推豎直方向战得,只需設(shè) android:height 為 0dp,然后設(shè) weight 屬性即可庸推!


二常侦、相對布局 Relative Layout

RelativeLayout 也是一種非常常用的布局,和 LinearLayout 的排列規(guī)則不同的是贬媒, RelativeLayout 顯得更加隨意一些聋亡,它總是通過相對定位的方式讓控件出現(xiàn)在布局的任何位置,比如說相對容器內(nèi)兄弟組件际乘、父容器的位置決定了它自身的位置杀捻。也正因為如此, RelativeLayout 中的屬性非常多蚓庭,不過這些屬性都是有規(guī)律可循的。

實現(xià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">
    <!-- 定義該組件位于父容器中間 -->
    <TextView
        android:id="@+id/view01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/leaf"
        android:layout_centerInParent="true"/>
    <!-- 定義該組件位于view01組件的上方 -->
    <TextView
        android:id="@+id/view02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/leaf"
        android:layout_above="@id/view01"
        android:layout_alignLeft="@id/view01"/>
    <!-- 定義該組件位于view01組件的下方 -->
    <TextView
        android:id="@+id/view03"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/leaf"
        android:layout_below="@id/view01"
        android:layout_alignLeft="@id/view01"/>
    <!-- 定義該組件位于view01組件的左邊 -->
    <TextView
        android:id="@+id/view04"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/leaf"
        android:layout_toLeftOf="@id/view01"
        android:layout_alignTop="@id/view01"/>
    <!-- 定義該組件位于view01組件的右邊 -->
    <TextView
        android:id="@+id/view05"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/leaf"
        android:layout_toRightOf="@id/view01"
        android:layout_alignTop="@id/view01"/>
</RelativeLayout>
運行效果如下:
RelativeLayout 梅花布局效果

代碼稍微復(fù)雜一點仅仆,不過難以理解的也就兩個屬性器赞,一個是 android:layout_toxxxOf,這個是一個控件位于另一個控件上下左右的相對位置墓拜,另一個是android:layout_alignxxx港柜,表示一個控件與另一個控件對齊,這里我們列出更詳細的屬性規(guī)則:

相對位置規(guī)則:
android:layout_above 將該控件的底部至于給定ID的控件之上
android:layout_below 將該控件的頂部至于給定ID的控件之下
android:layout_toLeftOf 將該控件的右邊緣和給定ID的控件的左邊緣對齊
android:layout_toRightOf 將該控件的左邊緣和給定ID的控件的右邊緣對齊
兄弟控件對齊規(guī)則:
android:layout_alignBaseline 將該控件的baseline和給定ID的控件的baseline對齊
android:layout_alignBottom 將該控件的底部邊緣與給定ID控件的底部邊緣對其
android:layout_alignTop 將給定控件的頂部邊緣與給定ID控件的頂部對齊
android:layout_alignLeft 將該控件的左邊緣與給定ID控件的左邊緣對齊
android:layout_alignRight 將該控件的右邊緣與給定ID控件的右邊緣對齊
父控件對齊規(guī)則:
android:alignParentBottom 如果該值為true,則將該控件的底部和父控件的底部對齊
android:layout_alignParentLeft 如果該值為true夏醉,則將該控件的左邊與父控件的左邊對齊
android:layout_alignParentRight 如果該值為true爽锥,則將該控件的右邊與父控件的右邊對齊
android:layout_alignParentTop 如果該值為true,則將空間的頂部與父控件的頂部對齊
中央位置規(guī)則:
android:layout_centerVertical 如果值為真畔柔,該控件將被至于垂直方向的中央
android:layout_centerHorizontal 如果值為真氯夷,該控件將被至于水平方向的中央
android:layout_centerInParent 如果值為真,該控件將被至于父控件水平方向和垂直方向的中央
重力規(guī)則:
android:gravity[setGravity(int)]設(shè)置容器內(nèi)各個子組件的重力方向
android:ignoreGravity[setIgnoreGravity(int)]設(shè)置容器哪個子組件的不受重力方向影響


三靶擦、幀布局 Frame Layout

Frame Layout 相比于前面兩種布局就簡單多了腮考,你可能因此就覺得它的應(yīng)用場景會少很多,不過也要看情況玄捕,如果是應(yīng)用在比較復(fù)雜的自定義布局的時候踩蔚,那么幀布局還是很受歡迎的,因為這種布局沒有任何的定位方式枚粘,所有的控件都會擺放在布局的左上角馅闽,不像其它布局那樣充滿了各種各樣的規(guī)則。當(dāng)你翻開幀布局的源碼的時候也會驚奇的發(fā)現(xiàn)相比于其它布局它的代碼量要少很多馍迄,這就導(dǎo)致了在復(fù)雜的自定義布局控件中選用幀布局作為父類的話就會一定程度上提升UI的渲染的性能福也。

實現(xiàn)一個疊加效果:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent">
    <!-- 依次定義6個TextView,先定義的TextView位于底層柬姚,后定義的TextView位于上層 -->
    <TextView
        android:id="@+id/view01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="160pt"
        android:height="160pt"
        android:background="#f00"/>
    <TextView
        android:id="@+id/view02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="140pt"
        android:height="140pt"
        android:background="#0f0"/>
    <TextView
        android:id="@+id/view03"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="120pt"
        android:height="120pt"
        android:background="#00f"/>
    <TextView
        android:id="@+id/view04"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="100pt"
        android:height="100pt"
        android:background="#ff0"/>
    <TextView
        android:id="@+id/view05"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="80pt"
        android:height="80pt"
        android:background="#f0f"/>
    <TextView
        android:id="@+id/view06"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="60pt"
        android:height="60pt"
        android:background="#0ff"/>
</FrameLayout>

運行起來的效果是:


FrameLayout 布局效果

幀布局容器為每個加入其中的組件創(chuàng)建一個空白的區(qū)域(即一幀)拟杉,每個子組件占據(jù)一幀,這些幀都會根據(jù)gracity屬性自動對齊并按照添加的順序先后疊加在一起量承。

FrameLayout的一些屬性:
android:foreground[setForeground(Drawable)] 定義幀布局容器的繪圖前景圖像
android:foregroundGravity[setForegroundGravity(int)] 定義繪圖前景圖像的重力屬性


四搬设、表格布局 Table Layout

Table Layout 允許我們使用表格的方式來排列控件。既然是表格撕捍,那就一定會有行和列拿穴,在設(shè)計表格時我們盡量應(yīng)該讓每一行都擁有相同的列數(shù),這樣的表格也是最簡單的忧风。不過有時候事情并非總會順從我們的心意默色,當(dāng)表格的某行一定要有不相等的列數(shù)時, 就需要通過合并單元格的方式來應(yīng)對狮腿。

下面的例子示范了如何用 Table Layout 來管理布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#3354fc"/>
    
    <!-- 定義第一個表格布局腿宰,指定第2列允許收縮,第3列允許拉伸 -->
    <TableLayout android:id="@+id/TableLayout01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:shrinkColumns="1"
        android:stretchColumns="2">
        <!-- 直接添加按鈕缘厢,它自己會占一行 -->
        <Button android:id="@+id/ok1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="獨自一行的按鈕"/>
        <!-- 添加一個表格行 -->
        <TableRow>
            <!-- 為該表格行添加三個按鈕 -->
            <Button android:id="@+id/ok2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="普通的一個按鈕"/>
            <Button android:id="@+id/ok3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="收縮按鈕"/>
            <Button android:id="@+id/ok4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="拉伸按鈕"/>
        </TableRow>
    </TableLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#3354fc"/>

    <!-- 定義第2個表格布局 吃度,指定第2列隱藏-->
    <TableLayout android:id="@+id/TableLayout02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:collapseColumns="1">
        <!-- 直接添加按鈕,它自己會占一行 -->
        <Button android:id="@+id/ok5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="獨自一行的按鈕"/>
        <!-- 添加一個表格行 -->
        <TableRow>
            <!-- 為該表格行添加三個按鈕 -->
            <Button android:id="@+id/ok6"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="普通按鈕1"/>
            <Button android:id="@+id/ok7"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="普通按鈕2"/>
            <Button android:id="@+id/ok8"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="普通按鈕3"/>
        </TableRow>
    </TableLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#3354fc"/>

    <!-- 定義第3個表格布局贴硫,指定第2列和第3列可以被拉伸-->
    <TableLayout
        android:id="@+id/TableLayout03"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="1,2">
        <!-- 直接添加按鈕椿每,它自己會占一行 -->
        <Button
            android:id="@+id/ok9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="獨自一行的按鈕"
            />
        <!--定義一個表格行-->
        <TableRow>
        <!-- 為該表格行添加三個按鈕 -->
        <Button
            android:id="@+id/ok10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="普通按鈕"
            />
        <Button
            android:id="@+id/ok11"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="拉伸的按鈕"
            />
        <Button
            android:id="@+id/ok12"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="拉伸的按鈕"
            />
        </TableRow>
        <!--定義一個表格行-->
        <TableRow>
            <!-- 為該表格行添加兩個按鈕 -->
            <Button
                android:id="@+id/ok13"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="普通按鈕"
                />
            <Button
                android:id="@+id/ok14"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="拉伸的按鈕"
                />
        </TableRow>
    </TableLayout>
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#3354fc"/>
</LinearLayout>
上面定義了三個 Table Layout 伊者,通過 TextView 分割開來并通過代碼指定了它們對各自列的控制行為:
  • 第一個TableLayout :指定第2列允許收縮,第3列允許拉伸
  • 第二個TableLayout :指定第2列隱藏
  • 第三個TableLayout :指定第2列和第3列可以被拉伸

并且上面的每個按鈕寬度所用的屬性都是 android:layout_width="wrap_content" 间护,正常來講按鈕只要包裹住美容即可亦渗,但是因為我們指定了相應(yīng)列的屬性,那么可以看到運行的效果如下:

TableLayout 布局效果

相關(guān)的屬性:
android:collapseColumns[setColumnCollapsed(int,boolean)] 設(shè)置需要被藏的列的列號汁尺,多個列號之間用逗號隔開
android:shrinkColumns[setShrinkAllColumns(boolean)] 設(shè)置允許被收縮的列的列號法精,多個列號之間用逗號隔開
android:stretchColumns[setStretchAllColumns(boolean)] 設(shè)置允許被拉伸的列的列號,多個列號之間用逗號隔開


五均函、網(wǎng)格布局 Grid Layout

GridLayout是Android4.0之后新增的布局管理器亿虽,因此正常情況下需要在 Android 4.0 之后的版本中才能使用,如果希望在更早的版本中使用的話苞也,需要導(dǎo)入相應(yīng)的支撐庫(v7包的gridlayout包)洛勉。

Grid Layout 和前面所講的 Table Layout(表格布局) 有點類似,不過他有很多前者沒有的東西如迟,因此也更加好用:

  • 可以自己設(shè)置布局中組件的排列方式
  • 可以自定義網(wǎng)格布局有多少行收毫、列
  • 可以直接設(shè)置組件位于某行某列
  • 可以設(shè)置組件橫跨幾行或者幾列

實現(xiàn)一個計算器界面:

<?xml version="1.0" encoding="utf-8" ?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:rowCount="6"
            android:columnCount="4"
            android:id="@+id/root">
    <!-- 定義一個橫跨4列的文本框,并設(shè)置該文本框的前景色殷勘、背景色等屬性  -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_columnSpan="4"
        android:textSize="50sp"
        android:layout_marginLeft="2pt"
        android:layout_marginRight="2pt"
        android:padding="3pt"
        android:layout_gravity="right"
        android:background="#eee"
        android:textColor="#000"
        android:text="0"/>
    <!-- 定義一個橫跨4列的按鈕 -->
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_columnSpan="4"
        android:text="清除"/>
</GridLayout>

首先在布局文件中定義了一個 6*4 的 Grid Layout此再,然后在該布局中添加兩個組件并且每個組件均橫跨4列,接下來在Java中動態(tài)添加16個按鈕:

public class MainActivity extends Activity
{
    GridLayout gridLayout;
    // 定義16個按鈕的文本
    String[] chars = new String[] {
                    "7" , "8" , "9" , "÷",
                    "4" , "5" , "6" , "×",
                    "1" , "2" , "3" , "-",
                    "." , "0" , "=" , "+"
            };
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        gridLayout = (GridLayout) findViewById(R.id.root);
        for(int i = 0 ; i < chars.length ; i++)
        {
            Button bn = new Button(this);
            bn.setText(chars[i]);
            // 設(shè)置該按鈕的字號大小
            bn.setTextSize(40);
            // 設(shè)置按鈕四周的空白區(qū)域
            bn.setPadding(5 , 35 , 5 , 35);
            // 指定該組件所在的行
            GridLayout.Spec rowSpec = GridLayout.spec(i / 4 + 2);
            // 指定該組件所在的列
            GridLayout.Spec columnSpec = GridLayout.spec(i % 4);
            GridLayout.LayoutParams params = new GridLayout.LayoutParams(
                    rowSpec , columnSpec);
            // 指定該組件占滿父容器
            params.setGravity(Gravity.FILL);
            gridLayout.addView(bn , params);
        }
    }
}

Java類中采用循環(huán)的方式向 Grid Layout 中添加了16個按鈕玲销,指定了每個按鈕所在的行號和列號输拇,并指定這些按鈕會自動填充單元格的所有空間——避免了單元格中的大量空白,運行效果如下:


Grid Layout 布局效果

以下為GridLayout常用屬性:

排列對齊:

  • 設(shè)置組件的排列方式: android:orientation="" vertical(豎直,默認)或者horizontal(水平)
  • 設(shè)置組件的對齊方式: android:layout_gravity=""[setGravity(int)] center,left,right,buttom,如果想同時用兩種的話:buttom|left
    設(shè)置布局為幾行幾列:
  • 設(shè)置有多少行:android:rowCount="4"[setrowCount(int)] //設(shè)置網(wǎng)格布局有4行
  • 設(shè)置有多少列:android:columnCount="4"[setColumnCount(int)] //設(shè)置網(wǎng)格布局有4列

設(shè)置某個組件位于幾行幾列:

  • 組件在第幾行:android:layout_row = "1" //設(shè)置組件位于第二行
  • 組件在第幾列:android:layout_column = "2" //設(shè)置該組件位于第三列
    設(shè)置某個組件橫跨幾行幾列:
  • 橫跨幾行:android:layout_rowSpan = "2" //縱向橫跨2行
  • 橫跨幾列:android:layout_columnSpan = "3" //橫向橫跨2列

其他設(shè)置:

  • 布局管理器采用的對齊方式:android:alignmentMode[setAlignmentMode(int)]
  • 布局管理器是否保留列序號:android:columnOrderPreserved[setColumnOrderPreserved(boolean)]
  • 布局管理器是否保留行序號:android:rowOrderPreserved[setRowOrderPreserved(boolean)]
  • 布局管理器是否使用默認的頁邊距:android:useDefaultMargins[setUseDefaultMargins(boolean)]

六贤斜、絕對布局 Absolute Layout

Absolute Layout 就像它名字所展現(xiàn)的那樣策吠,它不提供任何布局控制,而是由開發(fā)人員自己通過X瘩绒、Y坐標來控制組件的位置猴抹。所以絕大多數(shù)情況下我們是不采用絕對布局這種布局方式的,因為運行Android應(yīng)用的手機往往千差萬別锁荔,屏幕大小蟀给、分別率、屏幕密度等都可能存在較大的差異阳堕,使用絕對布局的話很難做機型適配跋理,因此我們了解這種布局方式即可。

先了解下代碼:

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 定義一個文本框恬总,使用絕對定位 -->
    <TextView
        android:layout_x="20dp"
        android:layout_y="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用戶名:"/>
    <!-- 定義一個文本編輯框前普,使用絕對定位 -->
    <EditText
        android:layout_x="80dp"
        android:layout_y="15dp"
        android:layout_width="wrap_content"
        android:width="250dp"
        android:layout_height="wrap_content" />
    <!-- 定義一個文本框,使用絕對定位 -->
    <TextView
        android:layout_x="20dp"
        android:layout_y="80dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="密  碼:"/>
    <!-- 定義一個文本編輯框越驻,使用絕對定位 -->
    <EditText
        android:layout_x="80dp"
        android:layout_y="75dp"
        android:layout_width="wrap_content"
        android:width="250dp"
        android:layout_height="wrap_content"
        android:password="true"/>
    <!-- 定義一個按鈕,使用絕對定位 -->
    <Button
        android:layout_x="130dp"
        android:layout_y="135dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登   錄"/>
</AbsoluteLayout>

使用絕對布局需要像上面這樣給每個子組件都指定 android:layout_x、android:layout_y 兩個定位屬性缀旁,這樣才控制得了每個子組件在容器中出現(xiàn)的位置记劈,運行得到的效果如下:

Absolute Layout 布局效果

實際上想要通過絕對布局達到以上的效果需要反復(fù)多次運行比對,很顯然這樣的編程方式要繁瑣的多并巍,而且在不同屏幕上的顯示效果差異巨大目木,這里給出Android中常用的距離單位:

px(像素):每個對應(yīng)屏幕上的一個點
dip或dp(device independent pixels,設(shè)備獨立像素):一種基于屏幕密度的抽象單位懊渡,在每英寸160點的顯示器上刽射,1dip=1px
sp(scaled pixels,比例像素):主要處理字體的大小剃执,可以根據(jù)字體大小首選項進行縮放
in(英寸):標準長度單位


Android 中布局的優(yōu)化常用措施介紹

1誓禁、盡可能減少布局的嵌套層級

可以使用 sdk 提供的 hierarchyviewer 工具分析視圖樹,幫助我們發(fā)現(xiàn)沒有用到的布局肾档。

2摹恰、不用設(shè)置不必要的背景,避免過度繪制

比如父控件設(shè)置了背景色怒见,子控件完全將父控件給覆蓋的情況下俗慈,那么父控件就沒有必要設(shè)置背景。

3遣耍、使用<include>標簽復(fù)用相同的布局代碼

4闺阱、使用<merge>標簽減少視圖層次結(jié)構(gòu)

該標簽主要有兩種用法:

1) 因 為 所 有 的 Activity 視 圖 的 根 節(jié) 點 都 是 Frame Layout , 因 此 如 果 我 們 的 自 定 義 的 布 局 也 是 Fragmen Layout 的時候那么可以使用 merge 替換舵变。
2) 當(dāng)應(yīng)用 Include 或者 View Stub 標簽從外部導(dǎo)入 xml 結(jié)構(gòu)時酣溃,可以將被導(dǎo)入的 xml 用 merge 作為根節(jié)點表示,這樣當(dāng)被嵌入父級結(jié)構(gòu)中后可以很好的將它所包含的子集融合到父級結(jié)構(gòu)中棋傍,而不會出現(xiàn)冗余的節(jié)點救拉。
<merge>只能作為 xml 布局的根元素。

5瘫拣、通過<ViewStub>實現(xiàn) View 的延遲加載

布局如下:
<ViewStub
android:id="@+id/vs"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:inflatedId="@+id/my_view"
android:layout="@layout/my_layout" />
Java核心代碼:
public void loadVS(View view){
ViewStub vs = (ViewStub) findViewById(R.id.vs);
View inflate = vs.inflate();
int inflatedId = vs.getInflatedId();
int id = inflate.getId();
Toast.makeText(this, "inflatedId="+inflatedId+"***"+"id="+id,
Toast.LENGTH_SHORT).show();

感謝優(yōu)秀的你跋山涉水看到了這里亿絮,不如關(guān)注下讓我們永遠在一起!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末麸拄,一起剝皮案震驚了整個濱河市派昧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拢切,老刑警劉巖蒂萎,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異淮椰,居然都是意外死亡五慈,警方通過查閱死者的電腦和手機纳寂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泻拦,“玉大人毙芜,你說我怎么就攤上這事≌眨” “怎么了腋粥?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長架曹。 經(jīng)常有香客問我隘冲,道長,這世上最難降的妖魔是什么绑雄? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任展辞,我火速辦了婚禮,結(jié)果婚禮上绳慎,老公的妹妹穿的比我還像新娘纵竖。我一直安慰自己,他們只是感情好杏愤,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布靡砌。 她就那樣靜靜地躺著,像睡著了一般珊楼。 火紅的嫁衣襯著肌膚如雪通殃。 梳的紋絲不亂的頭發(fā)上厕宗,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天画舌,我揣著相機與錄音,去河邊找鬼已慢。 笑死曲聂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的佑惠。 我是一名探鬼主播朋腋,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膜楷!你這毒婦竟也來了旭咽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤赌厅,失蹤者是張志新(化名)和其女友劉穎穷绵,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體特愿,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡仲墨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年勾缭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片目养。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡漫拭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出混稽,到底是詐尸還是另有隱情,我是刑警寧澤审胚,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布匈勋,位于F島的核電站,受9級特大地震影響膳叨,放射性物質(zhì)發(fā)生泄漏洽洁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一菲嘴、第九天 我趴在偏房一處隱蔽的房頂上張望饿自。 院中可真熱鬧,春花似錦龄坪、人聲如沸昭雌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烛卧。三九已至,卻和暖如春妓局,著一層夾襖步出監(jiān)牢的瞬間总放,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工好爬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留局雄,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓存炮,卻偏偏與公主長得像炬搭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子僵蛛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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