線性布局LinearLayout
前幾個小節的例程中,XML文件用到了LinearLayout布局,它的學名為線性布局。顧名思義,線性布局 像是用一根線把它的內部視圖串起來,故而內部視圖之間的排列順序是固定的,要么從左到右排列,要 么從上到下排列。在XML文件中,LinearLayout通過屬性android:orientation區分兩種方向,其中從左 到右排列叫作水平方向,屬性值為horizontal;從上到下排列叫作垂直方向,屬性值為vertical。如果LinearLayout標簽不指定具體方向,則系統默認該布局為水平方向排列,也就是默認android:orientation="horizontal"
.
下面做個實驗,讓XML文件的根節點掛著兩個線性布局,第一個線性布局采取horizontal水平方向,第 二個線性布局采取vertical垂直方向。然后每個線性布局內部各有兩個文本視圖,通過觀察這些文本視圖 的排列情況,從而檢驗線性布局的顯示效果。詳細的XML文件內容如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="橫排第一個"android:textSize="17sp"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="橫排第二個"android:textSize="17sp"android:textColor="#000000" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="豎排第一個"android:textSize="17sp"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="豎排第二個"android:textSize="17sp"android:textColor="#000000" /></LinearLayout>
</LinearLayout>
運行測試App,進入如下圖所示的演示頁面,可見horizontal為橫向排列,vertical為縱向排列,說明android:orientation的方向屬性確實奏效了。
除了方向之外,線性布局還有一個權重概念,所謂權重,指的是線性布局的下級視圖各自擁有多大比例 的寬高。比如一塊蛋糕分給兩個人吃,可能兩人平均分,也可能甲分三分之一,乙分三分之二。兩人平 均分的話,先把蛋糕切兩半,然后甲分到一半,乙分到另一半,此時甲乙的權重比為1:1。甲分三分之 一、乙分三分之二的話,先把蛋糕平均切成三塊,然后甲分到一塊,乙分到兩塊,此時甲乙的權重比為1:2。就線性布局而言,它自身的尺寸相當于一整塊蛋糕,它的下級視圖們一起來分這個尺寸蛋糕,有的 視圖分得多,有的視圖分得少。分多分少全憑每個視圖分到了多大的權重,這個權重在XML文件中通過 屬性android:layout_weight
來表達。
把線性布局看作蛋糕的話,分蛋糕的甲乙兩人就相當于線性布局的下級視圖。假設線性布局平均分為左 右兩塊,則甲視圖和乙視圖的權重比為1:1,意味著兩個下級視圖的layout_weight屬性都是1。不過視圖 有寬高兩個方向,系統怎知layout_weight表示哪個方向的權重呢?所以這里有個規定,一旦設置了layout_weight屬性值,便要求layout_width填0dp或者layout_height填0dp。如果layout_width填0dp,則layout_weight表示水平方向的權重,下級視圖會從左往右分割線性布局;如果layout_height填0dp,則layout_weight表示垂直方向的權重,下級視圖會從上往下分割線性布局。 按照左右均分的話,線性布局設置水平方向horizontal,且甲乙兩視圖的layout_width都填0dp,layout_weight都填1,此時橫排的XML片段示例如下:
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="橫排第一個"android:textSize="17sp"android:textColor="#000000" /><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="橫排第二個"android:textSize="17sp"android:textColor="#000000" />
</LinearLayout>
按照上下均分的話,線性布局設置垂直方向vertical,且甲乙兩視圖的layout_height都填0dp,layout_weight都填1,此時豎排的XML片段示例如下:
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="0dp"android:layout_weight="1"android:text="豎排第一個"android:textSize="17sp"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="0dp"android:layout_weight="1"android:text="豎排第二個"android:textSize="17sp"android:textColor="#000000" />
</LinearLayout>
把上面兩個片段放到新頁面的XML文件,其中第一個是橫排區域采用紅色背景(色值為ff0000),第二 個是豎排區域采用青色背景(色值為00ffff)。重新運行測試App,打開演示界面如下圖所示,可見橫 排區域平均分為左右兩塊,豎排區域平均分為上下兩塊。
相對布局RelativeLayout
線性布局的下級視圖是順序排列著的,另一種相對布局的下級視圖位置則由其他視圖決定。相對布局名 為RelativeLayout,因為下級視圖的位置是相對位置,所以得有具體的參照物才能確定最終位置。如果不設定下級視圖的參照物,那么下級視圖默認顯示在RelativeLayout內部的左上角。 用于確定下級視圖位置的參照物分兩種,一種是與該視圖自身平級的視圖;另一種是該視圖的上級視圖 (也就是它歸屬的RelativeLayout)。綜合兩種參照物,相對位置在XML文件中的屬性名稱說明見下表。
為了更好地理解上述相對屬性的含義,接下來使用RelativeLayout及其下級視圖進行布局來看看實際效果圖。下面是演示相對布局的XML文件例子:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="150dp" ><TextViewandroid:id="@+id/tv_center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:background="#ffffff"android:text="我在中間"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_center_horizontal"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:background="#eeeeee"android:text="我在水平中間"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_center_vertical"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:background="#eeeeee"android:text="我在垂直中間"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_parent_left"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:background="#eeeeee"android:text="我跟上級左邊對齊"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_parent_right"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:background="#eeeeee"android:text="我跟上級右邊對齊"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_parent_top"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:background="#eeeeee"android:text="我跟上級頂部對齊"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_parent_bottom"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="#eeeeee"android:text="我跟上級底部對齊"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_left_center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@+id/tv_center"android:layout_alignTop="@+id/tv_center"android:background="#eeeeee"android:text="我在中間左邊"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_right_center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@+id/tv_center"android:layout_alignBottom="@+id/tv_center"android:background="#eeeeee"android:text="我在中間右邊"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_above_center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@+id/tv_center"android:layout_alignLeft="@+id/tv_center"android:background="#eeeeee"android:text="我在中間上面"android:textSize="11sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_below_center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/tv_center"android:layout_alignRight="@+id/tv_center"android:background="#eeeeee"android:text="我在中間下面"android:textSize="11sp"android:textColor="#000000" />
</RelativeLayout>
上述XML文件的布局效果如下圖所示,RelativeLayout的下級視圖都是文本視圖,控件上的文字說明 了所處的相對位置,具體的控件顯示方位正如XML屬性中描述的那樣。
Java程序如下:
package com.example.chapter03;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;public class RelativeLayoutActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_relative_layout);}
}