android學習之旅(5)---佈局管理器

Android佈局管理器

佈局管理器可以管理安卓的應用界面裏的各種組件,根據運行平臺管理組件的大小、位置等。所有佈局管理器都是ViewGrop的子類,所有可以調用addView方法向佈局管理中添加組件,佈局管理器可以進行嵌套。

線性佈局管理器(LinearLayout)

LinearLayout可以控制組件橫向/縱向排列。線性佈局不會換行,組件一個挨着一個排列,如果組件的長、寬太大可能會導致其餘的組件不被顯示。
佈局還是推薦在XML中進行設置,雖然也可以是代碼來操作,但相比較而言還是有些不方便。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TestButton1">
    </Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TestButton2">
    </Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TestButton3">
    </Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TestButton4">
    </Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TestButton5">
    </Button>

</LinearLayout>

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ERPxpug8-1575445303459)(./LinearLayoutTest1.png)]
在這個佈局中寫了5個按鈕只正常顯示了3個,還有2個沒有被正常顯示。

常用操作

XML屬性 方法 說明
android:orientation setOrientation(int) 設置佈局管理器內組件的排列方式:horizontal(水平排列)、vertical(垂直排列)。
android:baselineAligned setBaselineAligned(boolean) 該屬性設爲false,將會組織該佈局管理器與子元素的基線對齊
android:divider setDividerDrawable(Drawable) 設置垂直佈局時兩個按鈕的分割線
android:gravity setGravity(int) 設置佈局管理器內組件的對齊方式。該屬性支持top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertical、clip_horizontal幾種,也可以同時指定多種對齊方式的組合,通過位或運算進行組合。
android:measureWithLargestChild setMeasureWithLargestChildEnabled(boolean) 當該屬性設爲ture時,所有帶權的子元素都會具有最大元素的最小尺寸。

由於LinearLayout包括的所有子元素都受LinearLayout.layoutParams控制,因此LinearLayout包含的都有以下的XML屬性。

XML屬性 說明
android:layout_gravity 指定該子元素在LinearLayout中的對齊方式
android:layout_weight 指定該子元素在LinearLayout中所佔的權重

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QhXqQhA9-1575445303464)(./LinearLayoutTest2.png)]通過權重控制按鈕的位置

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="TestButton1">
    </Button>
    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="TestButton2">
    </Button>
    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="TestButton3">
    </Button>
    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="TestButton4">
    </Button>
    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="TestButton5">
    </Button>

</LinearLayout>

按權重計算View的大小的規則:自身所佔權重的大小/全部權重[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VAIgTjki-1575445303467)(./LinearLayoutTest3.png)]

表格佈局(TableLayout)

TableLayout繼承了LinearLayout,所有其本質依然是線性佈局。表格佈局採用了行、列的形式來管理UI組件。在表格佈局不需要明確聲明包含幾行幾列,而是通過TableRow、其他組件來控制表格行數和列數。需要注意的是,在表格佈局中列的寬度有該列中最寬的那個段元個決定,整個表格佈局取決於父容器額寬度(默認總是佔滿父容器本身)。
在表格佈局管理器中,可以爲單元格設置以下3種行爲方式:

  • Shrinkable:如果某個列被設爲Shrinkable,那麼該列的所有單元格的寬度可以被收縮,以保證該表格能適應父容器的寬度。
  • Stretchable:如果某個列被設置爲Stretchable,那麼該列的所有單元格的寬度可以被拉伸,以保證組件能完全填滿表格空餘空間。
  • Collapsed:如果某個列被設爲Collapsed,那麼該列所有的單元格會被隱藏。
    TableLayout繼承了LinearLayout,所有TableLayout完全可以支持的全部XML屬性。除此之外,TableLayout還支持以下屬性:
XML屬性 相關方法 說明
android:collapseColumns setColumnCollapsed(int,boolean) 設置需要被隱藏的列序號。多個序列號之間用逗號隔開
android:shrinkColumns setShrinkAllColumns(boolean) 設置允許被收縮的列的列序號。多個列序號之間用逗號隔開
android:stretchColumns setStretchAllColumns(boolean) 設置允許被拉伸的列的列序號。多個列序號之間用逗號隔開

幀佈局(FrameLayout)

幀佈局直接繼承了ViewGroup組件,幀佈局容器爲每個加入其中的組件創建一個空白的區域(稱謂一幀),每個子組件佔據一幀,這些幀都會根據gravity屬性執行自動對齊。
FrameLayout常用操作

XML屬性 相關方法 說明
android:foreground setForeground(Drawable) 設置該幀佈局容器的前景圖像
android:foregroundGravity setForegroundGravity(int) 定義繪製前景圖像的gravity屬性

幀佈局示例程序1

<?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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="400dp"
        android:height="400dp"
        android:background="#ff0000">

    </TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="350dp"
        android:height="350dp"
        android:background="#aaf0f0">

    </TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="300dp"
        android:height="300dp"
        android:background="#0ff0f0">

    </TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="250dp"
        android:height="250dp"
        android:background="#ffff00">

    </TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="200dp"
        android:height="200dp"
        android:background="#00ff00">

    </TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="150dp"
        android:height="150dp"
        android:background="#0000ff">

    </TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:width="100dp"
        android:height="100dp"
        android:background="#ff00ff">

    </TextView>
</FrameLayout>

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Ibqr9eDV-1575445303470)(./LinearLayoutTest4.png)]

幀佈局示例程序2

MianActivity.java

在剛纔的xml文件種添加View的id,並在colors.xml中添加自己喜歡的顏色。

package com.kong.layouttest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

import java.sql.Time;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {
    int count=0;
    //定義顏色數組
    int colorArray[]={R.color.colorAccent,R.color.colorGreen, R.color.colorBlue,
            R.color.colorGreen, R.color.colorRed,R.color.colorYellow,R.color.colorPrimaryDark};
    //定義視圖數組
    int viewArray[]={R.id.view1,R.id.view2,R.id.view3,
            R.id.view4,R.id.view5,R.id.view6,R.id.view7};
    TextView textView[]=new TextView[viewArray.length];
    //消息處理函數
    Handler handler=new Handler()
    {
        //當接收到消息時的動作
        public void handleMessage(Message message)
        {
            if(message.what==0x123)
            {
                for(int i=0;i<viewArray.length;++i)
                {
                    textView[i].setBackgroundResource(colorArray[(i+count)%colorArray.length]);
                }
                ++count;
            }
            //調用父類方法
            super.handleMessage(message);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //調用父類的方法
        super.onCreate(savedInstanceState);
        setContentView(R.layout.framelayout);
        //給每個View賦值
        for(int i=0;i<viewArray.length;++i)
        {
            textView[i]=findViewById(viewArray[i]);
        }
        //創建一個定時器,其中的參數爲線程
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                //發送消息
                handler.sendEmptyMessage(0x123);
            }
        },0,300);
    }
}

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#6200EE</color>
    <color name="colorPrimaryDark">#3700B3</color>
    <color name="colorAccent">#03DAC5</color>
    <color name="colorRed">#ff0000</color>
    <color name="colorGreen">#00ff00</color>
    <color name="colorBlue">#0000ff</color>
    <color name="colorYellow">#ffff00</color>

</resources>

這樣就可以一個動態的顏色變化的效果

相對佈局(RelativeLayout)

相對佈局內子組件的位置總司相對兄弟組件、父容器來決定,因此這種佈局方式被成爲相對佈局。如果A組件的位置是由B組件的位置決定的,Android要求先定義B組件,再定義A組件。

  • android:gravity
    相關方法:setGravity(int) 設置該佈局容器內各子組件的對齊方式
  • andRoid:ignoreGravity
    相關方法:setIgnoreGravity(int) 設置那個組件不受gravity屬性的影響
    同時爲了控制佈局容器中各個子組件的佈局分佈,RelativeLayout提供了一個內部類:RelativeLayout:LayoutParams,該類提供了大量的XML屬性來控制RelativeLayout佈局容器中子組件的佈局分佈。
XML屬性(設置boolean值) 說明
android:layout_centerHorizontal 控制該子組件是否位於佈局容器的水平居中
android:layout_centerVertical 控制該子組件是否位於佈局容器的垂直居中
android:layout_centerInParent 控制該子組件是否位於佈局容器的中央位置
android:layout_alignParentBottom 控制該子組件是否與佈局容器底端對齊
android:layout_alignParentLeft 控制該子組件是否與佈局容器的左邊對齊
android:layout_alignParentRight 控制該子組件是否與佈局容器的右邊對齊
android:layout_alignParentTop 控制該子組件是否與佈局容器頂端對齊
XML屬性(設置ID值) 說明
android:layout_toRightOf 控制該子組件位於給出ID組件的右側
android:layout_toLeftOf 控制該子組件位於給出ID組件的左側
android:layout_above 控制該子組件位於給出ID的上方
android:layout_below 控制該子組件位於給出Id的下方
android:layout_alignTop 控制該子組件與給出ID組件的上邊界對齊
android:layout_alignBottom 控制該子組件與給出ID組件的下邊界對齊
android:layout_alignLeft 控制該子組件與給出IF組件的左邊界對齊
android:layout_alignRight 控制該子組件與給出ID組件的右組件對齊

示例程序

利用相對佈局是實現心型九宮格

<?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">

    <!--以第9張組件爲中心進行相對佈局-->
    <TextView
        android:id="@+id/view9"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:background="@drawable/p9">

    </TextView>

    <TextView
        android:id="@+id/view2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_toLeftOf="@id/view9"
        android:layout_centerVertical="true"
        android:background="@drawable/p2">

    </TextView>

    <TextView
        android:id="@+id/view6"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_toRightOf="@id/view9"
        android:layout_centerVertical="true"
        android:background="@drawable/p6">

    </TextView>

    <TextView
        android:id="@+id/view4"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@id/view9"
        android:layout_centerHorizontal="true"
        android:background="@drawable/p4">

    </TextView>

    <TextView
        android:id="@+id/view8"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@id/view9"
        android:layout_centerHorizontal="true"
        android:background="@drawable/p8">

    </TextView>

    <TextView
        android:id="@+id/view1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@id/view2"
        android:layout_alignParentLeft="true"
        android:background="@drawable/p1">
    </TextView>

    <TextView
        android:id="@+id/view3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@id/view2"
        android:layout_alignParentLeft="true"
        android:background="@drawable/p3">
    </TextView>

    <TextView
        android:id="@+id/view5"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@id/view6"
        android:layout_alignParentRight="true"
        android:background="@drawable/p5">
    </TextView>

    <TextView
        android:id="@+id/view7"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@id/view6"
        android:layout_alignParentRight="true"
        android:background="@drawable/p7">
    </TextView>


</RelativeLayout>

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OKp0ix9Z-1575445303473)(./心型九宮格.png)]

網格佈局(GridLayout)

網格佈局時Android4.0之後新增的佈局管理器,因此需要在Android4.0之後的版本纔可以使用。網格佈局的作用類似於HTML中的table標籤,他把整個容器劃分爲rowsXColumns個網格,每個網格可以放置一個組件,除此之外,也可以設置一個組件橫跨幾行幾列。其中通過setRowCount(int)和setColumnCount(int)方法控制在網格的行數量和列數量。

XML屬性 相關方法 說明
android:alignmentMode setAlignmentMode(int) 設置該佈局管理器採用的對齊模式
android:columnCount setColumnCount(int) 設置該網格的列數量
android:columnOrderPreserved setColumnOrderPreserved(boolean) 設置該網格容器是否保留列序號
android:rowCount setRowCount(int) 設置該網格的行數量
android:rowOrderPreserved setRowOrderPreserved(boolean) 設置該網格容器是否保留行序號
android:useDefaultMargins setUseDefaultMargins(boolean) 設置該佈局管理器是否使用默認的頁邊距

爲了控制GridLayout佈局容器中個子組件的佈局分佈,GridLayout提供了一個內部類:GridLayout.LayoutParams,該類提供了大量的XML屬性來控制GridLayout佈局容器中子組件的佈局分佈。

XML屬性 說明
android:layout_column 設置該子組件在GridLayout的第幾行
android:layout_columnSpan 設置該子組件在GridLayout橫向上跨幾行
android:layout_gravity 設置該子組件採用何種方式佔據該網格的空間(setGravity(int))
android:layout_row 設置該子組件在GridLayout的第幾行
android:layout_rowSpan 設置該子組件在GridLayout縱向上跨幾行

除了上述的幾種佈局之外,android還提供了一種絕對佈局的方式,絕對佈局時不建議使用的,因爲它的佈局不會根據設備的不同的而改變。

android中常用的佈局單位

  • PX(像素):每個像素對應屏幕上的一個點
  • dip/dp(device independent pixels,設備獨立像素):一種基於屏幕密度的抽象單位。在每英寸160點的顯示器上,1dp=1px,但隨着屏幕密度的改變,dp於px的換算會發生改變,在編程中一遍建議使用dp。
  • sp(scaled Pixels,比例像素):主要處理字體的大小,可以根據用戶的字體大小首選項進行縮放。
  • in(英寸):標準長度單位
  • pt(磅):1磅=1/72英寸
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章