这是我参与更文挑战的第19天,活动详情查看: 更文挑战
关注我的公众号 “安安安安卓” 学习更多知识
StateFlow和Livedata
两者异同
如果你仔细去了解的话会发现StateFlow和Livedata有很多相似之处。两者都是用来观察数据的,非常适合用来做响应式开发。
不过两者也有不同之处的:
- StateFlow构造中有默认值,Livedata没有
- Livedata只有生命周期处于started或resumed状态的时候才能收到数据更新,而StateFlow即使退到后台也可以收到数据。
冷流热流
冷流:消费者调用收集collect方法的时候生产者才会开始发射数据,如下代码示例就是冷流。
(2..9).asFlow().collect{
println(it)
}
复制代码
热流:本文中StateFlow就是热流,即使不调用collect方法生产者也会发射数据。
Livedata使用
关于Livedata可以查看我前些天的文章
StateFlow使用
使用StateFlow实现数据监听
StateFlow可以通过setValue来更改数据状态
下面简单介绍一下用法:
- 添加activity和lifecycle扩展库
implementation 'androidx.activity:activity-ktx:1.2.2'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
复制代码
- viewmodel中添加StateFlow代码
private val mutableStateFlow = MutableStateFlow("安安安安卓")//构造中需要有初始值
val stateFlow: StateFlow<String> = mutableStateFlow//这里为什么要赋值给stateFlow呢,因为stateFlow是不能对value进行赋值的,MutableStateFlow是可以的,这样做可以避免用户在activity中有更新数据的行为
fun changeData(data: String) {
mutableStateFlow.value = data//发送数据
}
复制代码
- activity中的数据监听处理
当我们点击按钮的时候调用viewModel的changeData方法,更新flow的数据。
btnSendData.setOnClickListener {
viewModel.changeData("公众号:安安安安卓")
}
lifecycleScope.launch {//这里是运行在主线程的,所以下面的代码可以进行更新ui
viewModel.stateFlow.collect {
tvShowData.text = it
}
}
复制代码
- 实现效果
本例实现了下面的效果,首次进入页面StateFlow发送默认值:”安安安安卓”,点击按钮后调用ViewModel的changeData方法更新数据,在TextView中展示。
这里的使用与Livedata基本一致,不过下一个例子你就会发现StateFlow的模板代码更少,更简洁
使用StateFlow实现MediatorLiveData的效果
关于MediatorLiveData你可以看我这篇文章:
那么同样的效果使用StateFlow改如何实现呢,下面上代码:
上StateFlow实现的代码:
- 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
}
}
复制代码
- 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 次"
}
}
复制代码
- 实现效果
这里只使用了很少量的代码就实现了上一篇Livadata中的demo效果,所以StateFlow真的很好,而且它的好肯定不止这些的,需要进一步挖掘
关注我的公众号 “安安安安卓” 学习更多知识
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END