美文网首页
Kotlin-可观测属性委托(Observable)-Deleg

Kotlin-可观测属性委托(Observable)-Deleg

作者: 蒋斌文 | 来源:发表于2021-06-23 19:06 被阅读0次

Kotlin-可观测属性委托(Observable)-Delegates.observable Delegates.vetoable

委托属性在实际开发中是有如下4种使用情况的

1、延迟属性。

2、可观测属性。

3、非空属性。

4、map属性。

可观测属性委托(Observable)

public inline fun <T> observable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Unit):
        ReadWriteProperty<Any?, T> =
    object : ObservableProperty<T>(initialValue) {
        override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = onChange(property, oldValue, newValue)
image-20210623184629054

定义一个这个可观测的属性委托:

class Person {
    var age: Int by Delegates.observable(20) {
        prop, oldValue, newValue -> println("${prop.name}, oldValue: $oldValue, newValue: $newValue")
    }
}
image-20210623184854293

来调用一下:

fun main(args: Array<String>) {

    val person = Person()
    person.age = 30
    person.age = 40
}

RUN> 🏄🏄🏄🏂🏂🏂🤽♀️🤽♀️🤽♀️

age, oldValue: 20, newValue: 30
age, oldValue: 30, newValue: 40

可以追踪值得变化

读一读它的javadoc的说明:

Returns a property delegate for a read/write property that calls a specified callback function when changed.
Params:
initialValue - the initial value of the property.
onChange - the callback which is called after the change of the property is made. The value of the property has already been changed when this callback is invoked.
Samples:
samples.properties.Delegates.observableDelegate
image-20210623185244760

返回针对读写属性的一个代理,该代表会在值发生改变时去调用指定的回调函数

image-20210623185358482

该回调是当属性的改变发生进行调用的。当该回调函数被调用也就意味着该属性的值已经发生改变了

image-20210623185550205
public interface ReadWriteProperty<in T, V> : ReadOnlyProperty<T, V> {
    /**
     * Returns the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @return the property value.
     */
    public override operator fun getValue(thisRef: T, property: KProperty<*>): V

    /**
     * Sets the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @param value the value to set.
     */
    public operator fun setValue(thisRef: T, property: KProperty<*>, value: V)
}
image-20210623185651065

该基类接口能够被用于实现只读属性的属性委托。
它只是为了提示一个便利:你并不需要继承这个接口,只要你的属性委托拥有相同签名的方法既可。

对于这个observable方法是监听值改变之后的结果,那有没有能监听值改变之前做点东东的么?答案是有的,就是紧挨着observable()方法下面这个:

/**
 * Returns a property delegate for a read/write property that calls a specified callback function when changed,
 * allowing the callback to veto the modification.
 * @param initialValue the initial value of the property.
 * @param onChange the callback which is called before a change to the property value is attempted.
 *  The value of the property hasn't been changed yet, when this callback is invoked.
 *  If the callback returns `true` the value of the property is being set to the new value,
 *  and if the callback returns `false` the new value is discarded and the property remains its old value.
 *
 *  @sample samples.properties.Delegates.vetoableDelegate
 *  @sample samples.properties.Delegates.throwVetoableDelegate
 */
public inline fun <T> vetoable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Boolean):
        ReadWriteProperty<Any?, T> =
    object : ObservableProperty<T>(initialValue) {
        override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)
    }
image-20210623185842547

返回针对读写属性的一个属性委托,当属性发生变化时会调用指定的回调函数,并且允许该回调来否决这种修改

image-20210623185944790

尝试着对属性的值进行修改之前该方法会被调用。当回调被调用时,该属性的值其实还未被修改。

如果这个回调返回true则属性的值就会被设置成新值,而如果该回调返回false则新的值就会被丢弃,并且属性会保持老的值。

下面来试一下该方法:

class Person2 {
    var age: Int by Delegates.vetoable(20) {
        prop, oldValue, newValue -> when {
            oldValue <= newValue -> true
            else -> false
        }
    }
}
fun main(args: Array<String>) {
    val person2 = Person2()
    println(person2.age)

    person2.age = 40
    println(person2.age)

    println("========")

    person2.age = 30
    println(person2.age)

    println("--------")

  
}

RUN > 🏂🏂🏂🏄🏄🏄🏄🚣🚣🚣🚣

20
40
========
40
--------

下面对其进行总结一下:

Delegates.observable接收两个参数:初始值与修改处理器

处理器会在我们每次对属性赋值时得到调用(在赋值完成之后被调用),处理器本身接收3个参数:被赋值的属性本身,旧的属性值与新的属性值

Delegates.vetoable的调用时机与Delegates.observable相反,它是在对属性赋值之前被调用,根据Delegates.vetoable的返回结果是true还是false,来决定是否真正对属性进行赋值。

相关文章

网友评论

      本文标题:Kotlin-可观测属性委托(Observable)-Deleg

      本文链接:https://www.haomeiwen.com/subject/dbzbyltx.html