Flow是冷流。简单来说。如果Flow有了订阅者Collector以后,发射出来的值才会存在内存中,
这和懒加载的概念很像
与之相对的是热流,StateFlow和SharedFlow 是热流,在垃圾回收之前,都是存在内存之中,
并且处于活跃状态
StateFlow 是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新,还可通过其value属性读取当前状态值。
和livedata很像。
package com.example.android_flow_practice.viewmodel
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
class NumberViewModel : ViewModel() {
val number = MutableStateFlow(0)
fun increment() {
number.value++
}
fun deincrement() {
number.value--
}
}
fragment
package com.example.android_flow_practice.fragment
import android.os.Bundle
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.android_flow_practice.R
import com.example.android_flow_practice.databinding.FragmentArticleBinding
import com.example.android_flow_practice.databinding.FragmentNumberBinding
import com.example.android_flow_practice.viewmodel.ArticleViewModel
import com.example.android_flow_practice.viewmodel.NumberViewModel
import kotlinx.coroutines.flow.collect
class NumberFragment : Fragment() {
private val TAG = "NumberFragment"
private val viewModel: NumberViewModel by viewModels()
private val mBinding: FragmentNumberBinding by lazy {
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)
mBinding.apply {
btAdd.setOnClickListener { viewModel.increment() }
btSubtraction.setOnClickListener { viewModel.deincrement() }
}
lifecycleScope.launchWhenCreated {
viewModel.number.collect {
mBinding.tvText.text = it.toString()
}
}
}
}
布局
<?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"
android:orientation="vertical"
tools:context=".fragment.NumberFragment">
<TextView
android:id="@+id/tv_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="10dp"
android:text="0"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/bt_add"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="+" />
<Button
android:id="@+id/bt_subtraction"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="-" />
</LinearLayout>
</LinearLayout>