Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

hoc081098/DemoCoroutinesChannelResult

Repository files navigation

DemoCoroutinesChannelResult

Use Kotlinx Coroutines Channel to send and receive events between Fragments.

Hits

Overview

1. Create MainSingleEvent class.

sealed interface MainSingleEvent<out T : MainSingleEvent<T>> {
 interface Key<out T : MainSingleEvent<T>>
 val key: Key<T>
 data class HomeFragmentResult(val text: String) : MainSingleEvent<HomeFragmentResult> {
 override val key = HomeFragmentResult
 companion object : Key<HomeFragmentResult>
 }
 data class DashboardFragmentResult(val text: String) : MainSingleEvent<DashboardFragmentResult> {
 override val key = DashboardFragmentResult
 companion object : Key<DashboardFragmentResult>
 }
 data class HomeDetailsResult(val text: String) : MainSingleEvent<HomeDetailsResult> {
 override val key = HomeDetailsResult
 companion object : Key<HomeDetailsResult>
 }
 companion object {
 val KEYS: Set<Key<SomeMainSingleEvent>> = setOf(
 HomeFragmentResult,
 DashboardFragmentResult,
 HomeDetailsResult,
 )
 }
}

2. Create MainVM class with buffered channels as event bus.

class MainVM : ViewModel() {
 private val eventChannels: Map<MainSingleEvent.Key<SomeMainSingleEvent>, Channel<SomeMainSingleEvent>> =
 MainSingleEvent.KEYS.associateBy(
 keySelector = { it },
 valueTransform = { Channel<MainSingleEvent<SomeMainSingleEvent>>(Channel.UNLIMITED) }
 )
 fun <T : MainSingleEvent<T>> sendEvent(event: T) {
 checkNotNull(eventChannels[event.key]) { "Must register ${event.key} in MainSingleEvent.Companion.KEYS before using!" }
 .trySend(event)
 .getOrThrow()
 .also { Log.d("@@@", "Sent $event") }
 }
 @Suppress("UNCHECKED_CAST")
 fun <T : MainSingleEvent<T>, K : MainSingleEvent.Key<T>> receiveEventFlow(key: K): Flow<T> =
 checkNotNull(eventChannels[key]) { "Must register $key in MainSingleEvent.Companion.KEYS before using!" }
 .receiveAsFlow()
 .map { it as T }
}

3. Send and receive events in Fragments.

We will share MainVM instance between Fragments using Activity as owner.

private val mainVM by viewModels<MainVM>(
 ownerProducer = { requireActivity() }
)
// send in HomeFragment
mainVM.sendEvent(MainSingleEvent.HomeFragmentResult("Hello from HomeFragment"))
// receive in others
mainVM.receiveEventFlow(MainSingleEvent.HomeFragmentResult)
 .onEach { Log.d("###", "Received $it") }
 .launchIn(lifecycleScope)

AltStyle によって変換されたページ (->オリジナル) /