StateFlow当值发生变化,就会将值发送出去,下流就可以接收到新值。在某些场景下,StateFlow比LiveData更适用
效果:
1.定义ViewModel
StateFlow需要初始值
package com.aruba.flowapplyapplication.viewmodel
import 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.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StateFlowFragment">
<TextView
android: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.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.09" />
<Button
android: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" />
<Button
android: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.Guideline
android: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>
<variable
name="stateFlowViewModel"
type="com.aruba.flowapplyapplication.viewmodel.StateFlowViewModel" />
</data>
</layout>
3.Fragment中绑定ViewModel
package com.aruba.flowapplyapplication
import 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.launch
class 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 = stateFlowViewModel
binding.lifecycleOwner = viewLifecycleOwner
return binding.root
}
}
网友评论