Flow为上流发射,下流接收,是一对一的,而SharedFlow可以一对多,发射一次,多端接收
效果:
1.定义一个类,来对MutableSharedFlow对象作操作
package com.aruba.flowapplyapplication.common
import kotlinx.coroutines.flow.MutableSharedFlow
/**
* Created by aruba on 2021/9/21.
*/
object LocalEventBus {
val event = MutableSharedFlow<Event>()
suspend fun postEvent(e: Event) {
event.emit(e)
}
}
data class Event(val timestamp: Long)
2.定义ViewModel,来开启和停止SharedFLow发射
package com.aruba.flowapplyapplication.viewmodel
import android.view.View
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.aruba.flowapplyapplication.common.Event
import com.aruba.flowapplyapplication.common.LocalEventBus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
/**
* Created by aruba on 2021/9/21.
*/
class SharedFlowViewModel : ViewModel() {
private lateinit var job: Job
fun start(v: View) {
job = viewModelScope.launch(Dispatchers.IO) {
while (true) {
LocalEventBus.postEvent(Event(System.currentTimeMillis()))
}
}
}
fun stop(v: View) {
job.cancel()
}
}
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 com.aruba.flowapplyapplication.databinding.FragmentSharedFlowBinding
import com.aruba.flowapplyapplication.viewmodel.SharedFlowViewModel
class SharedFlowFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentSharedFlowBinding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_shared_flow,
container, false
)
val sharedFlowViewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory(requireActivity().application)
).get(SharedFlowViewModel::class.java)
binding.sharedFlowViewModel = sharedFlowViewModel
return binding.root
}
}
布局文件:
<?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">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SharedFlowFragment">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/timeFragment1"
android:name="com.aruba.flowapplyapplication.TimeFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<fragment
android:id="@+id/timeFragment2"
android:name="com.aruba.flowapplyapplication.TimeFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<fragment
android:id="@+id/timeFragment3"
android:name="com.aruba.flowapplyapplication.TimeFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:layout_margin="10dp"
android:onClick="@{sharedFlowViewModel.start}"
android:src="@drawable/ic_baseline_play_arrow_24" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="10dp"
android:onClick="@{sharedFlowViewModel.stop}"
android:src="@drawable/ic_baseline_stop_24" />
</FrameLayout>
<data>
<variable
name="sharedFlowViewModel"
type="com.aruba.flowapplyapplication.viewmodel.SharedFlowViewModel" />
</data>
</layout>
4.子Fragment中对SharedFlow收集
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.lifecycleScope
import com.aruba.flowapplyapplication.common.LocalEventBus
import com.aruba.flowapplyapplication.databinding.FragmentTimeBinding
import kotlinx.coroutines.flow.collect
class TimeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = DataBindingUtil.inflate<FragmentTimeBinding>(
inflater,
R.layout.fragment_time,
container,
false
)
lifecycleScope.launchWhenCreated {
LocalEventBus.event.collect {
binding.textView3.text = it.timestamp.toString()
}
}
return binding.root
}
}
布局文件就一个TextView