var items: List<Item> by
Delegates.observable(listOf()) { _, _, _ ->
notifyDataSetChanged()
}
var key: String? by
Delegates.observable(null) { _, old, new ->
Log.e("key changed from $old to $new") 9
}
// View and resource binding example in Android
private val button: Button by bindView(R.id.button)
private val textSize by bindDimension(R.dimen.font_size)
private val doctor: Doctor by argExtra(DOCTOR_ARG)
// Dependency Injection using Koin
private val presenter: MainPresenter by inject()
private val repository: NetworkRepository by inject()
private val vm: MainViewModel by viewModel()
// Data binding
private val port by bindConfiguration("port")
private val token: String by preferences.bind(TOKEN_KEY)
var token: String? = null
get() {
print("token returned value $field")
return field
}
set(value) {
print("token changed from $field to $value")
field = value
}
var attempts: Int = 0
get() {
print("attempts returned value $field")
return field
}
set(value) {
print("attempts changed from $field to $value")
field = value
}
尽管它们的类型不同,但这两个属性的行为几乎相同。 这似乎是一个可重复的模式,在我们项目中可能会有许多地方需要它,因此可以使用属性委托来提取此行为。 委托基于这样一种思想:属性是有它的访问器定义的 —— val 中的 getter 和 var 中的 getter 和 setter —— 这些方法可以委托给另一个对象的方法。 getter 将被委托给 getValue 函数, 而 setter 将被委托给 setValue 函数。然后我们将这样的对象放在 by 关键字的右侧,为了和上面的例子保持完全相同的属性行为,我们可以创建下面的委托:
var token: String? by LoggingProperty(null)
var attempts: Int by LoggingProperty(0)
private class LoggingProperty<T>(var value: T) {
operator fun getValue(
thisRef: Any?,
prop: KProperty<*>
): T {
print("${prop.name} returned value $value")
return value
}
operator fun setValue(
thisRef: Any?,
prop: KProperty<*>,
newValue: T
) {
val name = prop.name
print("$name changed from $value to $newValue")
value = newValue
}
}