1. 程式人生 > >Kotlin入門(19)Android的基礎佈局

Kotlin入門(19)Android的基礎佈局

線性佈局

線性佈局LinearLayout是最常用的佈局,顧名思義,它下面的子檢視像是用一根線串了起來,所以其內部檢視的排列是有順序的,要麼從上到下垂直排列,要麼從左到右水平排列。排列順序只能指定一維方向的檢視次序,可是手機螢幕是個二維的平面,這意味著還剩另一維方向需要指定檢視的對齊方式。故而線性佈局主要有以下兩種屬性設定方法: 1. setOrientation: 設定內部檢視的排列方向。LinearLayout.HORIZONTAL表示水平佈局,LinearLayout.VERTICAL表示垂直佈局。 2. setGravity: 設定內部檢視的對齊方式。Gravity.LEFT表示靠左對齊、Gravity.RIGHT表示靠右對齊、Gravity.TOP表示靠上對齊、Gravity.BOTTOM表示靠下對齊、Gravity.CENTER表示居中對齊。 空白距離margin和間隔距離padding是另外兩個常見的檢視概念,margin指的當前檢視與周圍檢視的距離,而padding指的是當前檢視與內部檢視的距離。這麼說可能有些抽象,接下來還是做個實驗,看看它們的顯示效果到底有什麼不同。下面是個實驗用的佈局檔案內容,通過背景色觀察每個檢視的區域範圍:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <!-- 外層佈局的背景色是藍色 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#00aaff" >
        <!-- 中間佈局的背景色是黃色 -->
        <LinearLayout
            android:id="@+id/ll_margin"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#ffff99" >
            <!-- 內層檢視的背景色是紅色 -->
            <View
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#ff0000" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

與上述佈局檔案對應的頁面Kotlin程式碼如下,根據不同的按鈕分別設定不同方向上的margin和padding數值:

//該頁面用於演示margin和padding的區別
class LinearLayoutActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_linear_layout)
        //設定ll_margin內部檢視的排列方式為水平排列
        ll_margin.orientation = LinearLayout.HORIZONTAL
        //設定ll_margin內部檢視的對齊方式為居中對齊
        ll_margin.gravity = Gravity.CENTER
        btn_margin_vertical.setOnClickListener {
            //Kotlin對變數進行型別轉換的關鍵字是as
            val params = ll_margin.layoutParams as LinearLayout.LayoutParams
            //setMargins方法為設定該檢視與外部檢視的空白距離
            //此處設定左邊和右邊的margin空白距離為50dp
            params.setMargins(0, dip(50), 0, dip(50))
            ll_margin.layoutParams = params
        }
        btn_margin_horizontal.setOnClickListener {
            val params = ll_margin.layoutParams as LinearLayout.LayoutParams
            //此處設定頂部和底部的margin空白距離為50dp
            params.setMargins(dip(50), 0, dip(50), 0)
            ll_margin.layoutParams = params
        }
        //setPadding方法為設定該檢視與內部檢視的間隔距離
        btn_padding_vertical.setOnClickListener {
            //此處設定左邊和右邊的padding間隔距離為50dp
            ll_margin.setPadding(0, dip(50), 0, dip(50))
        }
        btn_padding_horizontal.setOnClickListener {
            //此處設定頂部和底部的padding間隔距離為50dp
            ll_margin.setPadding(dip(50), 0, dip(50), 0)
        }
    }
}

依據頁面程式碼例子,Kotlin程式碼與Java程式碼的寫法有以下三點區別: 1. Kotlin允許對屬性orientation直接賦值,從而取代了setOrientation方法;類似的還有屬性gravity取代了setGravity方法; 2. Kotlin使用關鍵字as進行變數的型別轉換; 3. Kolin支援呼叫dip方法將dip數值轉換為px數值,倘若由Java編碼則需開發者自己實現一個畫素轉換的工具類; 因為dip方法來自於Kotlin擴充套件的Anko庫,所以需要在Activity程式碼頭部加上下面一行匯入語句:

import org.jetbrains.anko.dip

既然用到了Anko庫,自然要修改模組的build.gradle,在dependencies節點中補充下述的anko-common包編譯配置:

    compile "org.jetbrains.anko:anko-common:$anko_version"

Anko庫除了提供dip方法,還提供了sp、px2dip、px2sp、dimen等畫素單位的轉換方法,具體的方法說明見下表。 dip    將dip單位的數值轉換為以px為單位的數值 sp    將sp單位的數值轉換為以px為單位的數值 px2dip    將px單位的數值轉換為以dip為單位的數值 px2sp    將px單位的數值轉換為以sp為單位的數值 dimen    將dip單位的數值轉換為以sp為單位的數值

相對佈局

由於線性佈局的檢視排列方式比較固定,既不能重疊顯示也不能靈活佈局,因此複雜一些的介面往往用到相對佈局RelativeLayout。相對佈局內部的檢視位置不依賴於排列規則,而依賴於指定的參照物,這個參照物可以是與該檢視平級的檢視,也可以是該檢視的上級檢視(上級檢視即相對佈局自身)。有了參照物之後,還得指定當前檢視位於參照物的哪個方向,才能確定該檢視的具體位置。 在程式碼中指定參照物及其所處方位,呼叫的是佈局引數物件的addRule方法,方法格式形如“addRule(方位型別, 參照物的資源ID)”。下面是個給相對佈局新增下級檢視的Kotlin程式碼例子:

    //根據參照物與方位型別新增下級檢視
    private fun addNewView(align: Int, referId: Int) {
        var v = View(this)
        v.setBackgroundColor(Color.GREEN)
        val rl_params = RelativeLayout.LayoutParams(100, 100)
        rl_params.addRule(align, referId)
        v.layoutParams = rl_params
        v.setOnLongClickListener { vv -> rl_content.removeView(vv); true}
        rl_content.addView(v)
    }

程式碼裡的方位型別有多種取值,比如RelativeLayout.LEFT_OF表示位於指定檢視的左邊,RelativeLayout.ALIGN_RIGHT表示與指定檢視右側對齊,RelativeLayout.CENTER_IN_PARENT表示位於上級檢視中央等等。舉個例子,讓某檢視位於指定檢視上方,且與上級檢視的左側對齊,則呼叫addRule方法的Kotlin程式碼如下所示:

    rl_params.addRule(RelativeLayout.ABOVE, 指定檢視的資源ID)
    rl_params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 上級檢視的資源ID)

由此可見,常規的addRule呼叫程式碼有點冗長,因此Kotlin利用Anko庫將相對位置進行了簡化,具體辦法是引入擴充套件函式實現相對位置的設定,譬如above方法代表位於指定檢視上方,alignParentLeft方法代表與上級檢視的左側對齊。於是原來的Kotlin程式碼簡化如下:

    rl_params.above(指定檢視的資源ID)
    rl_params.alignParentLeft()

因為這幾個新方法來自於Anko庫,所以要在程式碼頭部加上下面一行匯入語句:

import org.jetbrains.anko.*

另外要修改模組的build.gradle,在dependencies節點中補充下述的anko-common包編譯配置:

    compile "org.jetbrains.anko:anko-common:$anko_version"

除了above和alignParentLeft之外,Anko也提供了所有的相對位置設定方法,具體的對應關係說明見下表。 Anko庫的相對位置    RelativeLayout類的相對位置 leftOf    LEFT_OF sameTop    ALIGN_TOP above    ABOVE sameLeft    ALIGN_LEFT rightOf    RIGHT_OF     sameBottom    ALIGN_BOTTOM below    BELOW sameRight    ALIGN_RIGHT centerInParent    CENTER_IN_PARENT alignParentLeft    ALIGN_PARENT_LEFT centerVertically    CENTER_VERTICAL alignParentTop    ALIGN_PARENT_TOP centerHorizontally    CENTER_HORIZONTAL alignParentRight    ALIGN_PARENT_RIGHT alignParentBottom    ALIGN_PARENT_BOTTOM  

點此檢視Kotlin入門教程的完整目錄 __________________________________________________________________________ 開啟微信掃一掃下面的二維碼,或者直接搜尋公眾號“老歐說安卓”新增關注,更快更方便地閱讀技術乾貨。