天天看點

Android布局控件-LinearLayout

文章目錄

    • 1.線性布局 LinearLayout
    • 2.排列方式(orientation)
    • 3.擺放位置(gravity/layout_gravity)
      • 3.1 權重(layout_weight)
    • 4.總結

1.線性布局 LinearLayout

LinearLayout簡單來說就是線性布局,線性肯定是具有橫豎兩種方向的,水準和垂直。

在使用LinearLayout的時候,需要注意以下幾點

2.排列方式(orientation)

排列方式有水準和垂直兩種方式

在xml檔案中:

android:orientation="vertical"   // 垂直排列
android:orientation="horizontal" // 水準排列
           

在java代碼中:

linearLayout.setOrientation(LinearLayout.VERTICAL);  // 設定垂直排列
linearLayout.setOrientation(LinearLayout.HORIZONTAL);// 設定水準排列
           

這裡需要注意:

android:orientation=“vertical”,子View使用layout_gravity在垂直方向上的設定無效

android:orientation=“horizontal”,子View使用layout_gravity在水準方向上的設定無效

3.擺放位置(gravity/layout_gravity)

上面講到了排列問題,這裡在來講一下擺放問題

  • gravity是針對目前控件裡面内容的擺放,如果是容器,則針對的是容器裡面子view的擺放;如果是控件,則針對的是控件裡面内容的擺放。
  • layout_gravity是指目前控件在父控件裡面的擺放位置,不過需要注意的一點是父控件設定的gravity的級别要低于子控件設定的layout_gravity。

我們來分析其中的一種情況然後來做個總結。

LinearLayout的排列方式為vertical,優先級最高。當LinearLayout設定了gravity,都是在LinearLayout排列方式為vertical,LinearLayout設定了gravity之後的位置重新來進行排列的。如果子view設定了layout_gravity的話,那麼子View的排列方式按子View設定的為主,下面看個例子:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">
 
    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="hello"/>
 
    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:padding="5dp"
        android:text="hello"/>
 
    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="hello"/>
 
</LinearLayout>
           
Android布局控件-LinearLayout

可以看到第二個TextView設定的layout_gravity為center_vertical,表示生效的是layout_gravity為center_vertical。是以layout_gravity相當于隻設定了center_vertical(不生效)而沒有設定center_horizontal,所有就出現了圖中的情況。可以總結為如果父控件設定了gravity的同時,子View設定了layout_gravity,那麼以子View設定的為準。

3.1 權重(layout_weight)

  • layout_weight

在LinearLayout布局之中,權重也是一個很重要的屬性。簡單來說就是按比例來配置設定控件占用父控件的大小。

若C-child表示子布局聲明的大小,B-blank表示剩餘布局的大小,P-percent表示子布局占據父布局剩餘布局的比例,則子布局最終的實際大小R-reality為:

R = C + B * P
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
 
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_blue_dark"
        android:padding="5dp"
        android:text="left"/>
 
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:padding="5dp"
        android:text="right"/>
 
</LinearLayout>
           
Android布局控件-LinearLayout

我們來按照公式來計算

R = C + B * P = 0dp + (B-0dp-0dp) * (1/2) = (1/2)B

也就是父布局的1/2。

  • weightSum

LinearLayout有一個權重數量的标記:weightSum。在LinearLayout中沒有聲明weightSum時,預設的就是各個控件權重的總和。上面的例子,預設的weightSum就是2。接下來我們再看一個例子:

這裡我将weightSum設定為4。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="4"
    android:orientation="horizontal">
 
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_blue_dark"
        android:padding="5dp"
        android:text="left"/>
 
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:padding="5dp"
        android:text="right"/>
 
</LinearLayout>
           

布局的顯示如下:

Android布局控件-LinearLayout
  • 0dp與wrap_content

谷歌官方建議子布局的layout_width使用0dp,來分比例顯示布局,和wrap_content大同小異,當使用layout_weight時,都表示占據剩餘寬度或高度的比重。

但兩者有明顯差別。

使用0dp時,要考慮所配置設定的布局寬度是否小于控件實際寬度,比如:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_blue_dark"
        android:padding="5dp"
        android:text="left"/>
 
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="19"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:padding="5dp"
        android:text="right"/>
 
</LinearLayout>
           

則顯示為如下:

Android布局控件-LinearLayout

而使用wrap_content則不會出現上面的那種情況

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_blue_dark"
        android:padding="5dp"
        android:text="left"/>
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="19"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:padding="5dp"
        android:text="right"/>
 
</LinearLayout>
           
Android布局控件-LinearLayout

這裡left先擷取自适應的大小,然後再去擷取剩餘布局的1/20。

  • 0dp與match_parent

可以發現match_parent是與0dp的效果是相反的

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/holo_blue_dark"
        android:padding="5dp"
        android:text="left"/>
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:padding="5dp"
        android:text="right"/>
 
</LinearLayout>
           
Android布局控件-LinearLayout

這看起來很奇怪,那麼我們通過公式來計算。以left為例子

B是剩餘布局的大小 = 父布局大小 - 子控件大小之和

B = C - (C + C) = -C;

R = C + B * P = C + (-C) * (1/3) = 2/3C

這裡的C就是父布局的大小也就是match_parent。

4.總結

  • LinearLayout的排列方式有垂直和水準
  • 當LinearLayout的排列方式為vertical,也就是垂直方向時:

    LinearLayout裡面的子view設定layout_gravity在垂直方向上的設定是無效的。并且子view設定的layout_gravity是在前兩個的基礎位置上來進行擺放的。

  • 當LinearLayout的排列方式為horizontal,也就是水準方向時:

    LinearLayout裡面的子view設定layout_gravity在水準方向上的設定是無效的。并且子view設定的layout_gravity是在前兩個的基礎位置上來進行擺放的。

  • 權重需要記住的就是公式

    控件的實際大小 = 控件設定的大小 + (布局剩餘的大小) * 布局的比例

    布局剩餘的大小 = 父布局的大小 - 子布局大小之和