使用Kotlin開發Android應用(IV):自定義視圖和Android擴展

使用Kotlin開發Android應用(IV):自定義視圖和Android擴展

@author ASCE1885的 Github 簡書 微博 CSDN
原文鏈接

在讀完擴展函數和默認值這篇文章之后,那么接下來要介紹什么呢?在本系列第一篇文章中我們說過,Kotlin使得Android開發更加簡單,本文我們將進一步作介紹。

自定義視圖

你應該還記得,在說到Kotlin的局限性時,我們提到了在Kotlin早期版本(M10之前)是不支持自定義視圖的,因為當時只能為每個類創建一個構造函數。這通常是足夠的,因為使用可選參數,我們可以創建足夠多的構造函數變種,例如:

class MyClass(param: Int, optParam1: String = "", optParam2: Int = 1) 
{


    init {

        // Initialization code

    }

}

通過這一個構造函數,我們有如下四種方式創建這個類:

val myClass1 = MyClass(1)
val myClass2 = MyClass(1, "hello")
val myClass3 = MyClass(param = 1, optParam2 = 4)
val myClass4 = MyClass(1, "hello", 4)

正如你所見,使用可選參數我們得到了一堆的組合。但是通過繼承普通Views的方式來創建自定義Views時,我們可能會遇到問題。自定義Views需要重寫一個或者多個構造函數以便正常工作,但我們做不到這一點。幸運的是,自動Kotlin M11開始,我們可以聲明多個構造函數,類似Java。下面是一個正方形的ImageView:

class SquareImageView : ImageView {
 
    public constructor(context: Context) : super(context) {
    }
 
    public constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }
 
    public constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
    }
 
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val width = getMeasuredWidth()
        setMeasuredDimension(width, width)
    }
}

通過很簡單的代碼我們實現了自定義Views。

Kotlin Android擴展

從Kotlin M11開始增加的擴展插件使得Android開發者更容易取得XML文件中定義的Views。你可能會覺得它很像ButterKnife,但使用起來更簡單。

Kotlin Android擴展本質上是一個視圖綁定,使得開發者在代碼中通過id就可以使用XML文件中定義的Views。它將自動為Views創建屬性值,而不用使用第三方注解框架或者findViewById函數。

要使用這個特性,首先需要安裝插件“Kotlin Android Extension”,并在build.gradle文件的構建腳本依賴中增加一個新的classpath:

buildscript {

    …

    dependencies {
        …

        classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
    }

}

假如你定義了名為main.xml的布局文件:

<FrameLayout

    xmlns:android="..."

    android:id="@+id/frameLayout"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent">
 


    <TextView

        android:id="@+id/welcomeText"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"/>


 
</FrameLayout>

如果想在Activity中使用這個文件里面定義的Views,你只需要導入這個xml文件的synthetic屬性值,如下所示:

import kotlinx.android.synthetic.<xml_name>.*

具體到我們的例子,則如下所示:

import kotlinx.android.synthetic.main.*

這樣你就可以使用id來取得這些views的引用了:

override fun onCreate(savedInstanceState: Bundle?) {

    super<BaseActivity>.onCreate(savedInstanceState)
    setContentView(R.id.main)

    frameLayout.setVisibility(View.VISIBLE)

    welcomeText.setText("I′m a welcome text!!")

}

總結

這兩個新特性的引入,讓我們看到了Kotlin團隊致力于讓Android開發更簡單。他們也發布了一個名為Anko的函數庫,這個一門從Kotlin文件創建Android布局的領域特定語言(DSL)。我還沒有使用過它的主要功能,但當處理Android視圖時,你可以使用它來簡化代碼。在我上傳到Github上的開源項目Bandhook-Kotlin也有相關的例子。

下一篇文章將介紹lambda表達式的使用,以及它如何簡化代碼和擴展語言的特性。非常有趣的一個特性,在我看來,這是Kotlin相比Java 1.7最強大的方面。

歡迎關注我的微信公眾號

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容