Last active
September 1, 2024 15:35
-
-
Save hlayan/7025e63e71306d97f58343da68b77678 to your computer and use it in GitHub Desktop.
Single Event Solution for Kotlin Flow and Compose
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Event<out T>(private val _value: T?) { | |
private val used = AtomicBoolean(false) | |
val value: T? get() = if (used.compareAndSet(false, true)) _value else null | |
} | |
val EmptyEvent get() = Event(null) | |
typealias FlowEvent<T> = StateFlow<Event<T>> | |
typealias MutableFlowEvent<T> = MutableStateFlow<Event<T>> | |
fun <T : Any> mutableFlowEvent(): MutableFlowEvent<T> = MutableStateFlow(EmptyEvent) | |
fun <T : Any> MutableFlowEvent<T>.asFlowEvent(): FlowEvent<T> = asStateFlow() | |
fun <T : Any> MutableFlowEvent<T>.sendEvent(value: T) { | |
this.value = Event(value) | |
} | |
suspend fun <T : Any> FlowEvent<T>.collectEvent(action: suspend (value: T) -> Unit) { | |
collectLatest { value.value?.let { action(it) } } | |
} | |
@Composable | |
fun <T> EventEffect( | |
event: Event<T>, | |
block: suspend CoroutineScope.(T) -> Unit | |
) { | |
LaunchedEffect(event) { | |
event.value?.let { block(it) } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun EventScreen( | |
modifier: Modifier = Modifier, | |
viewModel: EventViewModel = hiltViewModel() | |
) { | |
val snackbarHostState = remember { SnackbarHostState() } | |
val snackBarEvent by viewModel.snackBarEvent.collectAsStateWithLifecycle() | |
EventEffect(event = snackBarEvent) { message -> | |
snackbarHostState.showSnackbar(message) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@HiltViewModel | |
class EventViewModel @Inject constructor( | |
savedStateHandle: SavedStateHandle, | |
) : ViewModel() { | |
private val _snackBarEvent = mutableFlowEvent<String>() | |
val snackBarEvent = _snackBarEvent.asFlowEvent() | |
fun showMessage() { | |
_snackBarEvent.sendEvent("Cannot refresh data!") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment