前言
学过Flow可以知道,这是一种冷流,就是订阅者使用的时候,flow发出的流才会保存在内存当中,这种模式更适合一些连续的,不变的的数据传输(已知),但是,我们在实际中可能需要可变的、实时更新的数据,这就需要使用StateFlow,与LiveData
类似,StateFlow
通常与视图相关联,并且在视图的生命周期内保持活动状态,(是一种热流,存在内存中,时刻保持活跃),还能通过value属性读取当前状态值
SharedFlow:功能类似广播,只是性质不一样,简单来讲就是一个流可以被多个收集到,也是一种热流。
下面用StateFlow为例,做一个简单的计数显示功能
前期工作使用了navigation组件,有不懂的可以看我之前写的
一、设置Fragment与布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.numberFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dip">
<TextView
android:id="@+id/tv_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="0"
android:textSize="30dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dip">
<Button
android:id="@+id/buttonnumber1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+"
android:textSize="30dp"/>
<Button
android:id="@+id/buttonnumber2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="-"
android:textSize="30dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
package com.example.applicationflow.fragment
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.example.applicationflow.R
import com.example.applicationflow.databinding.FragmentNumberBinding
import com.example.applicationflow.databinding.FragmentRoomBinding
import com.example.applicationflow.viewmodel.NumberViewModel
import kotlinx.coroutines.flow.collect
class numberFragment : Fragment() {
private val viewModel by viewModels<NumberViewModel>()//拿到viewModel
private val mBinding: FragmentNumberBinding by lazy{
Log.d("feng", "没有问题1")
FragmentNumberBinding.inflate(layoutInflater)//视图绑定的快捷方式
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return mBinding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//进行了视图绑定viewBinding可以直接使用
mBinding.apply {
buttonnumber1.setOnClickListener {
viewModel.increment()
}
buttonnumber2.setOnClickListener {
viewModel.decremnet()
}
}
//进行赋值
lifecycleScope.launchWhenCreated {
viewModel.number.collect{
value ->
mBinding.tvNumber.text = "$value"
}
}
}
}
二、设置ViewModel
package com.example.applicationflow.viewmodel
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
class NumberViewModel : ViewModel(){
//类似liveData
val number = MutableStateFlow(0)
fun increment(){
number.value++
}
fun decremnet(){
number.value++
}
}
三、运行如下
总结
这倒没啥难度,就当作理解stateFlow的使用和加强练习了