从 StateFlow 更新 RecyclerView 不起作用

问题描述 投票:0回答:1

当列表填充数据时,有没有办法(自动)更新

RecyclerView

我创建了一个简单的应用程序(这里是该应用程序的存储库)。 在

HomeFragment
中有一个
RecyclerView
和一个刷新数据的按钮。

只要我在

HomeFragment
中有以下代码,以便在
StateFlow
列表获取数据时更新适配器,该应用程序就可以正常工作。

private fun setupObservers() {
    lifecycleScope.launchWhenStarted {
        vm.state.collect() {
            if (it.list.isNotEmpty()) {
                todoAdapter.data = it.list
            } else {
                todoAdapter.data = emptyList()
            }
        }
    }
}

我的问题是,是否有办法让

RecyclerView
更新,而不必观察(或收集)
StateFlow
列表的变化?

android kotlin android-recyclerview kotlin-stateflow
1个回答
0
投票

当数据发生变化时,必须通知 RecyclerView 适配器。要么在收集器/观察器中执行此操作,要么必须在代码中执行可能影响数据的操作的每个位置主动执行此操作。所以,通过收集来做到这一点更容易,也更不容易出错。

旁注,代码中的 if/else 没有完成任何有用的事情。如果您最终仍然将空列表传递给适配器,则没有理由以不同的方式对待空列表。

使用

repeatOnLifecycle
(或
flowWithLifecycle
)比使用
launchWhenStarted
更正确。 看这里

private fun setupObservers() {
    vm.state.flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
        .onEach { todoAdapter.data = it.list }
        .launchIn(viewLifecycleOwner.lifecycleScope)
}

我个人喜欢使用这样的扩展函数,以使其在收集流量时更加简洁:

fun <T> Flow<T>.launchAndCollectWithLifecycle(
    lifecycleOwner: LifecycleOwner, 
    state: Lifecycle.State = Lifecycle.State.STARTED, 
    action: suspend (T) -> Unit
) = flowWithLifecycle(lifecycleOwner.lifecycle, state)
        .onEach(action)
        .launchIn(lifecycleOwner.lifecycleScope)

那么你的代码将变成:

private fun setupObservers() {
    vm.state.launchAndCollectWithLifecycle(viewLifecycleOwner) {
        todoAdapter.data = it.list
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.