如何避免MutableStateFlow Kotlin中的默认值

发布于 2025-02-06 05:00:58 字数 447 浏览 4 评论 0原文

我在项目中使用MutableStateFlow。当我们初始化mutableStateFlow对象时,我们需要给出默认值。

val topics = MutableStateFlow<List<String>>(emptyList())

当我收集此值时,

[null, "Hello", "world"]

我想在适配器中通过此列表。因此,有什么方法可以在传递适配器之前删除空对象,还是有更好的方法?

viewModel.topics.collect { topicsList ->
    println(topicsList)         // [null, "Hello", "world"]
    adapter.submitList(topicsList)
}

I am using MutableStateFlow in my project. When we initialise the MutableStateFlow object we need to give default value.

val topics = MutableStateFlow<List<String>>(emptyList())

when I collect this value

[null, "Hello", "world"]

I want to pass this list in adapter . So is there a way we can remove the null object before passing in adapter or Is there any better way ?

viewModel.topics.collect { topicsList ->
    println(topicsList)         // [null, "Hello", "world"]
    adapter.submitList(topicsList)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

鹊巢 2025-02-13 05:01:01

如果您不希望它具有强制性初始值,请改用mutableSharedFlow。如果您给它replay = 1onbufferoverflow = bufferoverflow.drop_oldestdistractununtilChanged(),它基本上是与没有sutableStateFlow的情况执行value。如果onbufferoverflow不是bufferoverflow.suspendtryemit将始终成功,以便您可以使用tryemit()而不是value =

private val _topics = MutableSharedFlow<List<String>>(
    replay = 1,
    onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val topics: Flow<List<String>> = _topics.distinctUntilChanged()

// emitting to the shared flow:
_topics.tryEmit(newValue)

If you don't want it to have an enforced initial value, use MutableSharedFlow instead. If you give it replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST, and distinctUntilChanged(), it's basically the same thing as a MutableStateFlow without the enforced value. And if onBufferOverflow is not BufferOverflow.SUSPEND, tryEmit will always succeed so you can use tryEmit() instead of value =.

private val _topics = MutableSharedFlow<List<String>>(
    replay = 1,
    onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val topics: Flow<List<String>> = _topics.distinctUntilChanged()

// emitting to the shared flow:
_topics.tryEmit(newValue)
合约呢 2025-02-13 05:01:01

由于它发出了字符串列表,因此您可以尝试以null这样的null初始化状态流

val topics = MutableStateFlow<List<String>?>(null)

,当您收集时,您可以检查发射值是否为null

viewModel.topics.collect { topicsList ->
    topicsList?.let { safeTopics ->
        adapter.submitList(safeTopics)
    }
}

Since it emits a list of strings you could try to initialise the StateFlow with a null like so

val topics = MutableStateFlow<List<String>?>(null)

And when you collect you can check if the emitted value is null or not

viewModel.topics.collect { topicsList ->
    topicsList?.let { safeTopics ->
        adapter.submitList(safeTopics)
    }
}
心清如水 2025-02-13 05:01:01

如果要忽略状态流的初始值,请设置初始值null或任何您想要的任何内容。然后,您可以在Flow上使用过滤器函数。

例如,初始值是null

launch {
    val topicsState = MutableStateFlow<List<String?>?>(null)

    topicsState.filterNotNull().map { topics -> topics.filterNotNull() }.onEach { topics ->
        println(topics)
    }.launchIn(this)

    launch {
        delay(1000)
        topicsState.update { listOf(null, "Hello", "world") }
    }
}

输出

[Hello, world]

If you want to ignore initial value of StateFlow, set initial value null or anything you want. Then you can use filter function on flow.

For example initial value is null

launch {
    val topicsState = MutableStateFlow<List<String?>?>(null)

    topicsState.filterNotNull().map { topics -> topics.filterNotNull() }.onEach { topics ->
        println(topics)
    }.launchIn(this)

    launch {
        delay(1000)
        topicsState.update { listOf(null, "Hello", "world") }
    }
}

Output

[Hello, world]
jJeQQOZ5 2025-02-13 05:01:01

如果我们给出了一个普通的通用类型密封类。

普通密封类

sealed class Resource<T>(val data: T? = null, val error: String? = null) {
    class Loading<T> : Resource<T>()
    class Success<T>(data: T) : Resource<T>(data = data)
    class Error<T>(error: String) : Resource<T>(error = error)
}

在这种情况下,我们可以设置这样的初始值。

private val _mutableStateFlow: MutableStateFlow<Resource<List<PackageModel>>?> = MutableStateFlow(null)

packageModel 是模型/pojo类

If we have given a common generic type sealed class.

Common Sealed Class

sealed class Resource<T>(val data: T? = null, val error: String? = null) {
    class Loading<T> : Resource<T>()
    class Success<T>(data: T) : Resource<T>(data = data)
    class Error<T>(error: String) : Resource<T>(error = error)
}

In that case, we can set the initial value like this.

private val _mutableStateFlow: MutableStateFlow<Resource<List<PackageModel>>?> = MutableStateFlow(null)

PackageModel is Model/Pojo class

誰ツ都不明白 2025-02-13 05:01:01

您只需使用drop(1)

viewModel.topics.drop(1).collect { topicsList ->
    ...
}

You can simply ignore the first value by using drop(1) :

viewModel.topics.drop(1).collect { topicsList ->
    ...
}
无风消散 2025-02-13 05:01:01

我认为您需要的是:

val sampleList = listOf(null, "Hello", "world")
val topics = MutableStateFlow<List<String>>(sampleList.filer { it != null })

I think what you need is this:

val sampleList = listOf(null, "Hello", "world")
val topics = MutableStateFlow<List<String>>(sampleList.filer { it != null })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文