Livedata用的爽吗?StateFlow让你更爽

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

关注我的公众号 “安安安安卓” 学习更多知识

StateFlow和Livedata

两者异同

如果你仔细去了解的话会发现StateFlow和Livedata有很多相似之处。两者都是用来观察数据的,非常适合用来做响应式开发。

不过两者也有不同之处的:

  • StateFlow构造中有默认值,Livedata没有
  • Livedata只有生命周期处于started或resumed状态的时候才能收到数据更新,而StateFlow即使退到后台也可以收到数据。

冷流热流

冷流:消费者调用收集collect方法的时候生产者才会开始发射数据,如下代码示例就是冷流。

 (2..9).asFlow().collect{
            println(it)
        }
复制代码

热流:本文中StateFlow就是热流,即使不调用collect方法生产者也会发射数据。

Livedata使用

关于Livedata可以查看我前些天的文章

juejin.cn/post/697568…

juejin.cn/post/697831…

StateFlow使用

使用StateFlow实现数据监听

StateFlow可以通过setValue来更改数据状态

下面简单介绍一下用法:

  1. 添加activity和lifecycle扩展库
implementation 'androidx.activity:activity-ktx:1.2.2'
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
复制代码
  1. viewmodel中添加StateFlow代码
 private val mutableStateFlow = MutableStateFlow("安安安安卓")//构造中需要有初始值
    val stateFlow: StateFlow<String> = mutableStateFlow//这里为什么要赋值给stateFlow呢,因为stateFlow是不能对value进行赋值的,MutableStateFlow是可以的,这样做可以避免用户在activity中有更新数据的行为

    fun changeData(data: String) {
        mutableStateFlow.value = data//发送数据
    }
复制代码
  1. activity中的数据监听处理

当我们点击按钮的时候调用viewModel的changeData方法,更新flow的数据。

  btnSendData.setOnClickListener {
            viewModel.changeData("公众号:安安安安卓")
        }
        lifecycleScope.launch {//这里是运行在主线程的,所以下面的代码可以进行更新ui
            viewModel.stateFlow.collect {
                tvShowData.text = it
            }
        }
复制代码
  1. 实现效果

本例实现了下面的效果,首次进入页面StateFlow发送默认值:”安安安安卓”,点击按钮后调用ViewModel的changeData方法更新数据,在TextView中展示。

这里的使用与Livedata基本一致,不过下一个例子你就会发现StateFlow的模板代码更少,更简洁

使用StateFlow实现MediatorLiveData的效果

关于MediatorLiveData你可以看我这篇文章:

juejin.cn/post/697568…

那么同样的效果使用StateFlow改如何实现呢,下面上代码:

上StateFlow实现的代码:

  1. ViewModel中代码声明
class StateFlowMediatorViewModel : ViewModel() {
    private var count1 = 0//第一个按钮点击的次数
    private var count2 = 0//第二个按钮点击的次数
    private val flow1 = MutableStateFlow(0)
    private val flow2 = MutableStateFlow(0)
    val flow = flow1.combine(flow2) { data1, data2 ->
        data1 + data2//将两个flow融合,分别点击的数量相加
    }

    fun flow1pp() {
        flow1.value = ++count1//点击第一个按钮数量加1
    }

    fun flow2pp() {
        flow2.value = ++count2//点击第二个按钮数量加1
    }
}
复制代码
  1. activity中代码声明
 findViewById<Button>(R.id.btn_mediator1).setOnClickListener {
            model.flow1pp()
        }
        findViewById<Button>(R.id.btn_mediator2).setOnClickListener {
            model.flow2pp()
        }

        lifecycleScope.launch {
            model.flow.collect {
                textView?.text = if (it > 10) "亲爱的安安安安卓同学您已经点击了$it 次了,再点也不和你玩了" else "您已经点击了$it 次"
            }
        }
复制代码
  1. 实现效果

这里只使用了很少量的代码就实现了上一篇Livadata中的demo效果,所以StateFlow真的很好,而且它的好肯定不止这些的,需要进一步挖掘

关注我的公众号 “安安安安卓” 学习更多知识

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享