解决方案:Kotlin Flow

阎唯
2023-12-01

限于篇幅原因及主题的原因(主题是 LiveData),直接给出代码(当前做法有问题),关于 LiveData vs Flow 的详细分析可以点击如何把业务代码越写越复杂?(二)| Flow 替换 LiveData 重构数据链路,更加 MVI
class MyViewModel : ViewModel() {
    // 商品列表流
    val selectsListFlow = MutableSharedFlow<List<String>>()
    // 更新商品列表
    fun setSelectsList(goods: List<String>) {
        viewModelScope.launch {
            selectsListFlow.emit(goods)
        }
    }
}
复制代码
购物车代码如下:
class TrolleyFragment : Fragment() {
    private val myViewModel by lazy { 
        ViewModelProvider(requireActivity()).get(MyViewModel::class.java) 
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 1.先产生数据
        myViewModel.setSelectsList(listOf("food_meet", "food_water", "book_1"))
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 2.再订阅商品列表流
        lifecycleScope.launch {
            myViewModel.selectsListFlow.collect { goods ->
                goods.takeIf { it.size >= 2 }?.let {
                    Log.v("ttaylor", "购物车满")
                }
            }
        }
    }
}
复制代码
数据生产在订阅之前,订阅后并不会打印 log。
如果这样修改 SharedFlow 的构建参数,则可以让其变得粘性:
class MyViewModel : ViewModel() {
    val selectsListFlow = MutableSharedFlow<List<String>>(replay = 1)
}
复制代码
replay = 1 表示会将最新的那个数据通知给新进的订阅者。
这只是解决了粘性/非粘性之间方便切换的问题,并未解决仍需多个流的问题。带下一篇继续深入分析。

 类似资料: