android 中布局的重要性不言而喻,一個好的布局能夠保持代碼的高效性以及整潔性。能夠在xml檔案中進行的互動盡量在xml檔案中進行布局,今天就寫寫android中的幾大布
局也算是這段時間給自己的總結。
android中所有和使用者進行互動的控制項都是繼承於View這個基類,最常見的如:TextView,EditText 等等。說到布局就不能不說到ViewGroup,這是個繼承於View的布局和視圖
容,官方文檔給其的定義為:
A ViewGroup is a special view that can contain other views (called children.) The view group is the base class for layouts and views containers. This
class also defines the ViewGroup.LayoutParams class which serves as the base class for layouts parameters.
(這是一個能夠容納其他views的特別view,這個view
容器是其他布局和視圖容器的基類,這個類也規定了LayoutParams作為基類的布局參數)。
基本上所有的布局類都是繼承於這個類,如果現有的布局已經不能夠滿足於你的需求,你可以繼承這個類自訂布局。下面給出布局和ViewGroup之間
的繼承關係:
上面的圖只是畫出了常見的布局之間的繼承關係。
下面來講解線性布局:LinearLayout的相關屬性及用法:
1:android:orientation:可選值為 vertical:垂直布局,即:每個控制項都是在其相鄰控制項的上或者下面。Horizontal :水平布局,即:每個控制項都在其相鄰控制項的左或者右邊
2:android:Layout_width 可選值為:wrap_content,match_parent, fill_parent。關於三者之間的區別,官方文檔是這樣介紹的:
fill_parent The view should be as big as its parent (minus padding). This constant is deprecated starting from API Level 8 and is replaced by match_parent
match_parent The view should be as big as its parent (minus padding). Introduced in API Level 8.
wrap_content The view should be only big enough to enclose its content (plus padding).
其實從Android 2.2開始fill_parent 改名為match_parent ,從API Level為8開始我們可以直接用match_parent 來代替fill_parent 。
3:android:grivaty ,android_layout_grivaty,其之間的區別為:
android:gravity是對元素本身說的,元素本身的文本顯示在什麼地方靠著換個屬性設定,不過不設定預設是在左側的。
android:layout_gravity是相對與它的父元素說的,說明元素顯示在父元素的什麼位置。
其可選屬性如下表格所示:
4:android:layout_weight ,android:layout_height
layout_weight 是線性布局專屬的屬性,很多人弄不清,為什麼有時候設定的值小反而佔據的空間大,有時候設定的值大反而佔據的空間小呢?在弄清這兩個差異首先我們
來瞭解一下match_parent 和wrap_content的差別。
match_parent 是此控制項在父布局盡量佔據較大的空間,wrap_content 是在完全將控制項的內容顯示出來的前提下,盡量佔據父布局較小的位置。所以如果我們將控制項的屬性
設定為match_parent時,設定layout_weight時,其值越小佔據的空間就越大,反之就越小。當我們將控制項的屬性設為wrap_content時,因為盡量其是佔據父布局較小的位置故
值越小其佔據的空間也就越小。(所以我們記憶的時候就只要記住layout_weight 的值越小其權重越大,這隻是為了記憶的方便,實際情況不是這樣的)
現在我們來說layout_weight 的數學計算方法:
(1)當控制項屬性為wrap_content:
我們設定三個控制項,其layout_weigh 為wrap_content ,layout_weight分別為1,2,3. 下面我們來看其所佔的比重:
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="50dip" android:background="#ffff0000" android:text="TextView1" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_weight="2" android:layout_height="50dip" android:background="#ff00ff00" android:text="TextView2" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_weight="3" android:layout_height="50dip" android:background="#7FFFD4" android:text="TextView2" /> </LinearLayout>
下面我們來看其效果:
我們可以看到,三個所佔螢幕的寬比分別為:1:2:3 ,也就是當控制項屬性為wrap_content時,按照正常的理解即: layout_weight 值越大所佔的比重越大。
(2)當控制項的屬性為match_parent時:
其實我們之前所說的layout_weight值越小權重越大,只是強制記憶而已,實際的計算方法為:
首先我們將上面那個xml檔案的控制項的屬性全改為,match_parent 然後設定layout_weight 分別為 1:2:2,接下來我們來計算其每個控制項所佔的比重,由於其每個屬性都為
match_parent 所以假設這個控制項原本所佔的空間為一個parent 那麼,這個控制項所佔的空間應為:自身的大小+所佔剩餘空間的比重。
第一個控制項所佔的空間的大小為=1p+(1p-3p)1/5=3p/5 這個計算方法為:原有的自身的大小+(原有的螢幕大小1p-3個控制項自身所佔的大小(3p))*自身所佔剩餘的比重,結果為
所佔據的空間大小,同理可得第二個控制項所佔大小為=1p+(1p-3p)*2/5=1p/5 ,同理第三個控制項所佔大小=1p+(1p-3p)*2/5=1p/5。如下:
我們還可以用另外一個比例去驗證一下:
當我們設定 三個的layout_weight 分別為1:2:3時:其效果為:
為什麼第三個控制項沒有顯示了呢?我們來按照什麼給出的計算方法去計算一下:第一個所佔空間=1p+(1p-3p)*1/6=2p/3,第二個所佔空間為=1p+(1p-3p)*2/6=1p/3
第三個所佔空間為:1p+(1p-3p)*3/6=0p 看算出的結果可知最後三個所佔的空間比為:2:1:0 故最後一個控制項沒有顯示出來。故驗證了上述計算方法的正確性。
因而:正確的記憶方法為:當屬性為wrap_content 其比例是按照正常的比例計算,當為match_parent或fill_parent時,layout_weight 越小其所佔剩餘比例就越小,通過計算其
比例就越大就是我們上述所說的值越小比例越大。
參考部落格:http://blog.csdn.net/softmanfly/article/details/7636510
接下來講一講 FramLayout布局的常用屬性及技巧:
FrameLayout 是一個比較簡單的版面配置容器,在這個布局中只能放置一個控制項,後面所有的控制項都會覆蓋掉其當前的控制項,每個添加的控制項都被固定在螢幕的左上方,要想設定
當中控制項在布局中的位置就必須通過 android:gravity 的屬性進行設定。例如布局訊息提醒的介面:
<FrameLayout android:background="@null" android:layout_width="match_parent" android:layout_height="fill_parent" android:layout_weight="3.5" > <LinearLayout android:gravity="bottom|center" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/sure" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:layout_gravity="center" android:background="@drawable/friendactivity_remind_normal" android:gravity="center" android:text="確定" android:textColor="#FFFFFF"/> </LinearLayout> <LinearLayout android:gravity="top|right|center" android:paddingRight="10.0dip" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:textSize="10.0dip" android:textColor="@android:color/white" android:gravity="center" android:id="@+id/tvTabUnread" android:background="@drawable/tab_unread_bg" android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2" /> </LinearLayout></FrameLayout>