代码之家  ›  专栏  ›  技术社区  ›  Barrufet

自定义保存程序remember可使用derivedStateOf保存

  •  0
  • Barrufet  · 技术社区  · 4 年前

    我有一个 rememberSaveable 有一些 derivedStateOf 进行一些计算以返回一个类作为输出。

    我已经在类中添加了Parceable/Parcelize,但它仍然崩溃,告诉我实现一个自定义保护程序。我相信这是因为我正在使用 嘲笑的状态 。 允许我从derivedStateOf的计算输出中保存状态吗?

    java.lang.IollegalArgumentException:无法使用当前SaveableStateRegistry保存DerivedState(值=MyClass(MyClass2()))。默认实现只支持可以存储在Bundle中的类型。请考虑为此类实现一个自定义Saver,并将其传递给rememberSaveable()。

    代码如下

    val someCalculation by rememberSaveable(someTriggering) {
            derivedStateOf {
                someCalculationThatReturnsAClass()
            }
        }
    
    0 回复  |  直到 4 年前
        1
  •  5
  •   Abokyy    4 年前

    您没有将自定义保存程序传递给您的 rememberSaveable() 。

    您感兴趣的rememberSaveable参数有:

    • inputs-一组输入,当其中任何一个发生更改时,将导致状态重置并重新运行init
    • saver-saver对象,定义如何保存和恢复状态

    您只将someTriggering作为输入进行传递。

    代码可能如下所示:

    val someCalculation by rememberSaveable(
       inputs = someTriggering,
       saver = YourCustomSaver
    ) {
        derivedStateOf {
            someCalculationThatReturnsAClass()
        }
    }
    

    在这里,您可以看到如何创建自定义保护程序: Saver documentation

    import androidx.compose.runtime.saveable.Saver
    
    data class Holder(var value: Int)
    
    // this Saver implementation converts Holder object which we don't know how to save
    // to Int which we can save
    val HolderSaver = Saver<Holder, Int>(
        save = { it.value },
        restore = { Holder(it) }
    )
    

    以及如何使用: rememberSaveable documentation

    import androidx.compose.runtime.saveable.rememberSaveable
    
    val holder = rememberSaveable(saver = HolderSaver) { Holder(0) }
    

    是否允许我保存来自的计算输出的状态 嘲笑的状态?

    是的,谷歌在他们的 Compose performance, use derivedStateOf 段落

    以下是他们添加的代码片段:

    val listState = rememberLazyListState()
    LazyColumn(state = listState) {
      // ...
      }
    
    val showButton by remember {
        derivedStateOf {
            listState.firstVisibleItemIndex > 0
        }
    }
    
    AnimatedVisibility(visible = showButton) {
        ScrollToTopButton()
    }