限于篇幅原因及主题的原因(主题是 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 表示会将最新的那个数据通知给新进的订阅者。
这只是解决了粘性/非粘性之间方便切换的问题,并未解决仍需多个流的问题。带下一篇继续深入分析。