通過 Kotlin 中的兩個接口:ReadOnlyProperty 和 ReadWriteProperty,可以方便的實現(xiàn)屬性委托或局部委托。對于 val 變量使用 ReadOnlyProperty,而 var 變量實現(xiàn)ReadWriteProperty。
這里通過 kotlin 實現(xiàn)委托獲取界面跳轉(zhuǎn)時 intent 傳遞的數(shù)據(jù):
fun <T> extraActivity(name: String): ActivityExtras<T?> = ActivityExtras(name, null)
fun <T> extraActivity(name: String, defaultValue: T) = ActivityExtras(name, defaultValue)
fun <T> extraFragment(name: String): FragmentExtras<T?> = FragmentExtras(name, null)
fun <T> extraFragment(name: String, defaultValue: T) = FragmentExtras(name, defaultValue)
class ActivityExtras<T>(private val name: String, private val defaultValue: T) :
ReadOnlyProperty<Activity, T> {
private var extra: T? = null
override fun getValue(thisRef: Activity, property: KProperty<*>): T {
return extra
?: thisRef.intent?.extras?.take<T>(name)?.also { extra = it }
?: defaultValue.also { extra = it }
}
}
class FragmentExtras<T>(private val name: String, private val defaultValue: T) :
ReadOnlyProperty<Fragment, T> {
private var extra: T? = null
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
return extra
?: thisRef.arguments?.take<T>(name)?.also { extra = it }
?: defaultValue.also { extra = it }
}
}
@Suppress("UNCHECKED_CAST")
fun <T> Bundle.take(key: String): T? {
try {
return get(key) as? T?
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
使用姿勢:
// 跳轉(zhuǎn)至 activity
val intent = Intent(context, xxx::class.java)
intent.putExtra("name", "candy")
context.startActivity(intent)
// activity 中獲取參數(shù)
private val mName by extraActivity<String>("name")
// fragment 傳遞參數(shù)
val fragment = XxxFragment()
fragment.arguments = Bundle().apply { putString("name", name) }
// fragment 中獲取參數(shù)
private val mName by extraFragment<String>("name")
就這么簡單。