繁体   English   中英

为什么我们不能在 jetpack compose 的 mutableStateListOf 中使用委托属性

[英]Why we cannot use delegate property in mutableStateListOf in jetpack compose

我想知道为什么我们不能在mutableStateListOf中使用委托属性。 当我试图添加

val favourites by remember { mutableStateListOf<Int>() }

它给我错误

Type 'TypeVariable(T)' has no method 'getValue(Nothing?, KProperty<*>)' and thus it cannot serve as a delegate

我也试过进口

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

但它仍然给出同样的错误。 这有什么具体原因吗? 谢谢

您应该问的是我如何将mutableStateOf与委托一起使用,因为默认情况下延迟不是任何 class 的一部分。

MutableState 委托实现为

/**
 * Permits property delegation of `val`s using `by` for [State].
 *
 * @sample androidx.compose.runtime.samples.DelegatedReadOnlyStateSample
 */
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> State<T>.getValue(thisObj: Any?, property: KProperty<*>): T = value

/**
 * Permits property delegation of `var`s using `by` for [MutableState].
 *
 * @sample androidx.compose.runtime.samples.DelegatedStateSample
 */
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> MutableState<T>.setValue(thisObj: Any?, property: KProperty<*>, value: T) {
    this.value = value
}

/**
 * A mutable value holder where reads to the [value] property during the execution of a [Composable]
 * function, the current [RecomposeScope] will be subscribed to changes of that value. When the
 * [value] property is written to and changed, a recomposition of any subscribed [RecomposeScope]s
 * will be scheduled. If [value] is written to with the same value, no recompositions will be
 * scheduled.
 *
 * @see [State]
 * @see [mutableStateOf]
 */
@Stable
interface MutableState<T> : State<T> {
    override var value: T
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}

您导入的函数

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

是上面代码段中的getValuesetValue函数。

您可以为类创建委托函数作为需要导入它们的扩展函数,或者作为 class 的一部分,如下例所示。

class CalculateDelegate {

    private var calculatedProperty = 0

    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return calculatedProperty
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
        calculatedProperty = value * 2
    }

}

/**
 * Delegate [CalculateDelegate] to this function
 */
fun delegateCalculationFunction() = CalculateDelegate()

如果您使用创建实例

var delegatedNum1 by CalculateDelegate()
var delegatedNum2 by delegateCalculationFunction()

然后,如果您将 setValue 更改或调用为

delegatedNum1 = 4
delegatedNum2 = 3

如果您打印这些 delegateNum1 和 delegateNum2,您将看到它们是 8 和 6,因为覆盖了setValue

如果您希望强制覆盖 class 的 setValue 和 getValue 函数,您可以使用 ReadWriteProperty 作为

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)
}

然后您需要重写getValuesetValue函数。

class CalculateDelegate: ReadWriteProperty<Any?, Int> {

    private var calculatedProperty = 0

    override operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return calculatedProperty
    }

    override operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
        calculatedProperty = value * 2
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM