天天看點

Android Layout研究 <二> Layout進階View

這篇blog大量參考網絡資源。

上面介紹一些基礎知識,接着研究研究UI的視圖層級。最後看看Layout中元素的屬性。

0. View:

先說說View:

View

extends Object

implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource

1.

2.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:background="#0099cc"

    >

    <Button

      android:id="@+id/button0"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_weight="0"

      android:width="250dp"

      android:height="100dp"

      android:text="@string/dummy_button" />

    <Button

      android:id="@+id/button1"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_marginLeft="10dp"

      android:padding="20dp"      

      android:layout_weight="0"

      android:text="@string/dummy_button" />

    <Button

      android:id="@+id/button2"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_gravity="right"

      android:layout_weight="0"

      android:text="@string/dummy_content" />

    <Button

      android:id="@+id/button3"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:gravity="right"

      android:layout_weight="0"

      android:text="@string/dummy_content" />

    <Button

      android:id="@+id/button4"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_weight="0"

      android:text="@string/Button" />

    <Button

      android:id="@+id/button5"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:layout_weight="0"

      android:text="@string/Button" />

</LinearLayout>

每個元素(view)都必須 layout_weight, layout_height。他們的取值有:wrap_content和fill_parent. 分别表示:隻包裹住内容和填充允許填充的部分。

以下具體分析:

分析一,layout_width,和width差別。

  <Button

      android:id="@+id/button0"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_weight="0"

      android:width="250dp"

      android:height="100dp"

      android:text="@string/dummy_button" />

android:id 可以将每個view唯一的辨別出來。在程式中,可以使用findViewById(R.id.xxxx)得到這個View。 并使用這個View句柄對這個元素作操作。

android:width, android:height: 這兩個值與layout_width和layout_height不同。

layout_width,layout_height表示目前View,也就是Button的大小。取值有:wrap_content(包裹内容),fill_parent(上層view允許的足夠大)

width,height表示Button上的Text的大小。取值是:xxxdp  (注1)

但這個大小其實要和其它參數配合使用。

例如:、

1.在以上設定中,Layout_width="wrap_content". 表示要能包住Text内容。如果不設定android:width. 則字元串dummy_button有多長,Button就顯示多長。

2. 加上了android:width="250dp". 情況就不同了。

如果Text内容長度短于250dp. 則因為它設定的内容寬度為250dp. 而Button的寬度是包裹住内容。是以Button真實寬度也是250dp. 因為android:width=250表示的就是内容寬度250dp.(隻是顯示不滿而已)

如果Text内容長度長于250dp. 但要顯示的内容是250.是以它會自動分行顯示。但也因為android:width=250表示的就是内容寬度250dp,而Layout_width為能包裹内容的長度。是以Button真實寬度為250dp.

3.如果layout_width="fill_parent". 則因為Button寬度足夠,是以android:width雖然等于250dp. 但也失去作用。 如果Text長度甚至大于整個寬度。則自動換行。

分析二:

layout_margin與padding.

雖然都是邊緣的空白,但從有無layout就能看出,一個是針對目前View,一個是針對View中的Text的。

layout_margin, layout_marginLeft, layout_marginRight等,都是說目前View和其它View之間的距離。

padding, paddingLeft,paddingRight等則是針對本View的Text和目前View的邊緣的。

    <Button

      android:id="@+id/button1"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_marginLeft="10dp"

      android:padding="20dp"      

      android:layout_weight="0"

      android:text="@string/dummy_button" />

android:layout_marginLeft="10dp":表明:Button左邊前一個View的左邊緣10dp.(下面詳細分析)

android:padding="20dp"   表明:Button裡面的字,距離Button的邊緣20dp.

android:layout_marginXXXX系列參數其實很簡單,但也容易造成誤解。現在詳細介紹如下:

舉例如下,LinearLayout中有三個Button。xml如下:

 <LinearLayout

        android:id="@+id/ll_bar"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:gravity="left|center_vertical"

        android:orientation="horizontal" >

        <Button

            android:id="@+id/bar_wifiInfo"

            android:layout_width="60dp"

            android:layout_height="60dp"

            android:layout_marginLeft="50dp"

            android:layout_marginRight="20dp"

            android:layout_marginTop="10dp"

            android:background="@drawable/wifi_network"

            android:enabled="false"

            android:focusable="false" />

        <Button

            android:id="@+id/bar_netInfo"

            android:layout_width="60dp"

            android:layout_height="60dp"

            android:layout_marginRight="10dp"

            android:layout_marginTop="10dp"

            android:background="@drawable/et_network"

            android:enabled="false"

            android:focusable="false" />

         <Button

            android:id="@+id/bar_Test"

            android:layout_width="60dp"

            android:layout_height="60dp"

            android:layout_marginLeft="10dp"

            android:layout_marginTop="10dp"

             />

    </LinearLayout>

Button1,中聲明如下:

android:layout_marginLeft="50dp"

android:layout_marginRight="20dp"

android:layout_marginTop="10dp"

android:layout_marginLeft="50dp": 則它的左邊距離父View的左邊為:50dp 

android:layout_marginTop="10dp":則它的上邊距離父View的上邊為:10dp.

android:layout_marginRight="20dp": 則它的右側要隔開距離為20dp. 即隔離線離它右邊20dp

Button2: 

android:layout_marginRight="10dp"   則它的右側要隔開距離為10dp.即隔離線距離它右邊10dp.

android:layout_marginTop="10dp"  : 則它的上邊距離父View的上邊為:10dp.

Button3:

android:layout_marginLeft="10dp" : 則它的左側離Button2隔開的隔離線為10dp

 android:layout_marginTop="10dp": 則它的上邊距離父View的上邊為:10dp.

那他們是怎麼分布的呢?

Sam引入一個隔離線的概念。

Button1中聲明右側隔離線距離它20dp. Button2聲明距離左側隔離線為0. 是以Button1距離Button2為:20+0=20dp

Button11中聲明右側隔離線距離它10dp.  Button3聲明距離左側隔離線為10dp. 是以Button2距離Button3: 10+10=20dp.

分析三:

layout_gravity, gravity差別:

    <Button

      android:id="@+id/button2"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_gravity="right"

      android:layout_weight="0"

      android:text="@string/dummy_content" />

    <Button

      android:id="@+id/button3"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:gravity="right"

      android:layout_weight="0"

      android:text="@string/dummy_content" />

同樣,layout_gravity是說View和它的上級View(父元素)的位置關系。gravity則是本View的Text和本View的位置關系。

 android:layout_gravity="right":這個Button在它的父元素的右邊對齊。

android:gravity="right":Button中的Text在Button的右邊對齊。

取值範圍:

top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertica

當 android:orientation="vertical"  時, 隻有水準方向的設定才起作用,垂直方向的設定不起作用。即:left,right,center_horizontal 是生效的。

當 android:orientation="horizontal" 時, 隻有垂直方向的設定才起作用,水準方向的設定不起作用。即:top,bottom,center_vertical 是生效的。

注1.

dp:density-independent pixels(獨立于密度的像素)——一個抽象的基于實體螢幕密度的機關。這些機關是相對于一個160dpi的螢幕,所有一個dp是160dpi螢幕上的一個點。dp到px的轉換比率根據螢幕密度改變,但不一定是成正比。

注2:

"weight"顧名思義是權重的意思,layout_weight 用于給一個線性布局中的諸多視圖的重要程度指派。所有的視圖都有一個layout_weight值,預設為零,意思是需要顯示多大的視圖就占據多大的螢幕空間。這就不難解釋為什麼會造成上面的情況了:Button1~Button5都設定了layout_height和layout_width屬性為wrap_content即包住文字内容,他們都沒有設定layout_weight 屬性,即預設為0.,這樣Button1和Button2根據需要的内容占據了整個螢幕,别的就顯示不了啦!

若賦一個高于零的值,則将父視圖中的可用空間分割,分割大小具體取決于每一個視圖的layout_weight值以及該值在目前螢幕布局的整體layout_weight值和在其它視圖螢幕布局的layout_weight值中所占的比率而定。舉個例子:比如說我們在 水準方向上有一個文本标簽和兩個文本編輯元素。該文本标簽并無指定layout_weight值,是以它将占據需要提供的最少空間。如果兩個文本編輯元素每一個的layout_weight值都設定為1,則兩者平分在父視圖布局剩餘的寬度(因為我們聲明這兩者的重要度相等)。如果兩個文本編輯元素其中第一個的layout_weight值設定為1,而第二個的設定為2,則剩餘空間的三分之二分給第一個,三分之一分給第二個(數值越小,重要度越高)。 

weight另一個好處就是允許子元素可以填充螢幕上的剩餘空間。這也避免了在一個大螢幕中,一串小對象擠 成一堆的情況,而是允許他們放大填充空白。子元素指定一個weight 值,剩餘的空間就會按這些子元素指定的weight 比例配置設定給這些子元素。預設的 weight 值為0。例如,如果有三個文本框,其中兩個指定了weight 值為1,那麼,這兩個文本框将等比例地放大,并填滿剩餘的空間,而第三個文本框 不會放大。

分割大小具體取決于每一個視圖的layout_weight值以及該值在目前螢幕布局的整體layout_weight值和在其它視圖螢幕布局的layout_weight值中所占的比率而定

這段說法有點不正确。例如Button:如果其Text長度不同,而layout_width="wrap_content". 則還與Text長度有關。