StateFlow当值发生变化,就会将值发送出去,下流就可以接收到新值。在某些场景下,StateFlow比LiveData更适用
效果:
1.定义ViewModel
StateFlow需要初始值
package com.aruba.flowapplyapplication.viewmodelimport android.view.View
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow/*** Created by aruba on 2021/9/21.*/
class StateFlowViewModel : ViewModel() {val stateFlow = MutableStateFlow<Int>(0)fun add(v: View) {stateFlow.value++}fun reduce(v: View) {stateFlow.value--}
}
2.Fragment的布局文件
DataBinding也支持在xml中直接使用StateFlow
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".StateFlowFragment"><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="24dp"android:text="@{String.valueOf(stateFlowViewModel.stateFlow)}"app:layout_constraintBottom_toTopOf="@+id/guideline2"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.13" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_percent="0.09" /><Buttonandroid:id="@+id/button6"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="24dp"android:onClick="@{stateFlowViewModel.add}"android:text="add"app:layout_constraintEnd_toStartOf="@+id/guideline3"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="@+id/guideline2" /><Buttonandroid:id="@+id/button7"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="24dp"android:text="reduce"android:onClick="@{stateFlowViewModel.reduce}"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="@+id/guideline3"app:layout_constraintTop_toTopOf="@+id/guideline2" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.5" /></androidx.constraintlayout.widget.ConstraintLayout><data><variablename="stateFlowViewModel"type="com.aruba.flowapplyapplication.viewmodel.StateFlowViewModel" /></data>
</layout>
3.Fragment中绑定ViewModel
package com.aruba.flowapplyapplicationimport android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.aruba.flowapplyapplication.databinding.FragmentStateFlowBinding
import com.aruba.flowapplyapplication.viewmodel.StateFlowViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launchclass StateFlowFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {val binding: FragmentStateFlowBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_state_flow,container,false)val stateFlowViewModel = ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(StateFlowViewModel::class.java)
// lifecycleScope.launch {
// stateFlowViewModel.stateFlow.collect {
// binding.textView2.text = it.toString()
// }
// }binding.stateFlowViewModel = stateFlowViewModelbinding.lifecycleOwner = viewLifecycleOwnerreturn binding.root}}