首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集合可组合转换的StateFlow

集合可组合转换的StateFlow
EN

Stack Overflow用户
提问于 2021-11-29 17:09:18
回答 1查看 544关注 0票数 3

函数collectAsState()适用于StateFlow属性,以便在Composable中观察它。

可组合需要StateFlow,因为StateFlow保证初始值。Flow并没有提供这样的保证。

现在,如果我有一个StateFlow属性,但是我想在收集Composable中的Flow之前应用一个操作符(比如map),那么该怎么做呢?

这里有一个例子:

假设存储库公开了一个StateFlow<MyClass>

代码语言:javascript
复制
val myClassStateFlow: StateFlow<MyClass>

data class MyClass(val a: String)

..。视图模型依赖于存储库,并且只希望将属性a公开给它的Composable.

代码语言:javascript
复制
val aFlow = myClassState.Flow.map { it.a } // <- this is of type Flow<String>

map运算符将类型从StateFlow<MyClass>更改为Flow<String>

  1. aFlow不再具有初始值,这在语义上是合理的吗?毕竟,它的第一次发射来自于myClassStateFlow的初始值。
  2. 在某个时候,需要将Flow转换回StateFlow。哪个地方更惯用呢?
    1. 在视图模型中使用stateIn()?代码会是什么样子?
    2. 在可组合中使用collectAsState(initial: MyClass)并给出一个初始值(尽管myClassStateFlow有一个初始值)?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-16 11:04:31

请参阅GitHub上的这个问题

目前还没有内置的方式来转换StateFlow,只有Flow,但是您可以自己编写。

我最终解决的方法是在那篇文章中使用这个例子。

首先创建一个DerivedStateFlow的概念。

代码语言:javascript
复制
class DerivedStateFlow<T>(
    private val getValue: () -> T,
    private val flow: Flow<T>
) : StateFlow<T> {

    override val replayCache: List<T>
        get () = listOf(value)

    override val value: T
        get () = getValue()

    @InternalCoroutinesApi
    override suspend fun collect(collector: FlowCollector<T>) {
        flow.collect(collector)
    }
}

然后在StateFlow上有一个扩展,就像当前map扩展在Flow上一样

代码语言:javascript
复制
fun <T1, R> StateFlow<T1>.mapState(transform: (a: T1) -> R): StateFlow<R> {
    return DerivedStateFlow(
        getValue = { transform(this.value) },
        flow = this.map { a -> transform(a) }
    )
}

现在,在您的存储库或ViewModel中,您可以如下所示使用它。

代码语言:javascript
复制
class MyViewModel( ... ) {
    private val originalStateFlow:StateFlow<SomeT>  = ...
    
    val someStateFlowtoExposeToCompose = 
        originalStateFlow
        .mapState { item -> 
            yourTransform(item)
        }
}

现在,您可以像您在撰写中所期望的那样使用它,而无需任何特殊的工作,因为它返回一个StateFlow

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70158579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档