Android Kotlin 開發需知

變量延遲加載

// 某些成員變量在聲明時無法初始化,且不想使用可空類型(也就是帶?的類型)。可使用 lateinit 和 by lazy

    // 不知道具體值,後面再賦值使用;所以必須var
    lateinit var name: String

    // 知道具體值,用到的時候再加載,表示不可變的值,所以必須val
    //  {}中的最後一行代碼返回初始化的結果,加載時機爲第一次調用常量的時候,且只會加載一次
    private val book by lazy {
        LogUtil.i("這行代碼不會影響book賦值")
        "Android"
    }

 訪問權限修飾符

    public:      公開,可見性最大,哪裏可以引用  Kotlin 的類默認是 public 的
    private:     私有,可見性最小,根據聲明位置不同可分爲類中可見和文件中可見
    protected:   保護,相當於private+ , 子類可見
    internal:    內部,僅對module內可見

構造方法,init代碼塊

/**
 * 構造函數單獨用了一個 constructor 關鍵字來和其他的 fun 做區分,分主構造和次構造
 * 如果類中有主構造器,所有次構造器都需要通過this關鍵字調用主構造器
 *
 * 從主構造器的特性出發,一旦在類中聲明瞭主構造器,就包含兩點:
 *     必須性:創建類的對象時,不管使用哪個構造器,都需要主構造器的參與
 *     第一性:在類的初始化過程中,首先執行的就是主構造器
 */
class User constructor(var name: String) {

    // init 代碼塊是先於次構造器執行的。
    init {
        // 如果把主構造器看成身體的頭部,那麼 init 代碼塊就是頸部,次構造器就相當於身體其餘部分
    }

    // 直接調用主構造器
    constructor(name: String, age: Int) : this(name)

    // 通過上一個次構造函數,間接調用主構造器
    constructor(name: String, age: Int, id: Int) : this(name, age) {}
    
}

 constructor 關鍵字省略,私有,參數

// 主構造器中 constructor 關鍵字如果沒有被 可見性修飾符 或 註釋 標註可以省略
class User(var name: String) {
    constructor(name: String, age: Int) : this(name)
}

// 主構造器被修飾爲私有的,外部就無法調用該構造器
class User private constructor(var name: String) {
}
// 主構造函數裏面聲明屬性,前面加 var / val 構造參數同時成爲成員變量
class User(var name: String) {
}

// ↑↓ 上下等價  
class User(name: String) {
    var name: String = name
}

靜態方法

一共三種實現方式:①object ②伴生對象 ③頂層函數

/**
 * 當用 object 聲明一個類時,表明這個類是一個單例類,可繼承其他類
 * object 可以定義在全局也可以在類的內部使用
 * object聲明不能用在方法和inner內部類中,但是能嵌套在其他object聲明和嵌套類中
 * object 定義後即刻實例化,因此 object 不能有定義構造函數
 */
object SystemUtil{
}


/**
 * 和 object 不同, companion object 的定義完全屬於類的本身,
 * 因此 companion object 不能脫離類而定義在全局之中。
 * 類似 Java 裏的 static 變量
 */
class ScreenUtil {

    // companion object 修飾爲伴生對象,伴生對象在類中只能存在一個
    companion object {

    }

}

真實項目中推薦的寫法是使用伴生對象和 object 關鍵字結合的方式,示例如下:

class UmengEventUtil {

    companion object {
        @JvmStatic
        fun getInstance(): UmengEventUtil {
            return Holder.instance
        }
    }

    private object Holder {
        val instance = UmengEventUtil()
    }

    fun onRegister(mContext: Context) {
        MobclickAgent.onEvent(mContext, "__cust_event_1")
    }
    
}

頂層聲明 top - level property / function

又稱頂層函數,直接在文件中定義函數和屬性,這種頂層函數不要聲明在module內最頂層的包中,至少要在一個包中

/*
頂層聲明屬於 package,不在 class/object 內
屬性和函數,不屬於任何 class,而是直接屬於 package
它和靜態變量、靜態函數一樣是全局的,用起來更方便:在其它地方用的時候,類名都不用寫
*/

fun stringToDouble(money: String): Double {
    return money.toDouble()
}

get,set 方法

// 默認kotlin已自動生產set,get方法,可省略
class User() {
     var name: String? = null
        set(value) {
            field = value
        }
        get() = field
}

// 上下等價   ↑↓
class User{
     var name: String? = null
}
// 如只想讓外部使用,不想外部set,可在set前面添加private將set方法私有化
class User {
    var name: String
        private set
    
    init {
        name = "設置name值,外部只能調用get方法"
    }
}

數據類

相比JavaBean手動生成各種方法,kotlin data class要簡單很多

/**
 *  var user = User("zs",18,"10001")
 * 自動生成
 * toString()       LogUtil.e("user.toString = $user")
 * copy()           var user2 = user.copy(id = 2)
 * equals()         user.equals(user2) 輸出 true
 * hashCode()       user.hashCode 輸出內存地址
 * componentN()     解構聲明   val (name, age, code) = User("zs", 0, "1001")
 */
data class User(
    var name: String,
    var age: Int,
    var code: String
)

擴展函數

// 原本使用
fun dp2px(dp: Float): Float {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics)
}

dp2px(3.4f)

// 擴展函數
fun Float.dp2px(): Float {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, Resources.getSystem().displayMetrics)
}

3.2f.dp2px()

 

持續更新中...

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章