Instantly share code, notes, and snippets.
Created Jul 14, 2021
HandleEventsAndStateWithSharedFlowAndStateFlow
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
// ViewModel with SharedFlow and StateFlow | |
abstract class BaseViewModel<STATE, EVENT : UiEvent, EFFECT : UiEffect>( | |
initialState: UiState<STATE> = UiState.Loading | |
) : ViewModel() { | |
... | |
// Get Current State | |
val currentState: UiState<STATE> | |
get() = uiState.value | |
private val _uiState: MutableStateFlow<UiState<STATE>> = MutableStateFlow(initialState) | |
val uiState = _uiState.asStateFlow() | |
private val _event: MutableSharedFlow<EVENT> = MutableSharedFlow() | |
val event = _event.asSharedFlow() | |
protected fun setUiEvent(newEvent: EVENT) { | |
viewModelScope.launch { _event.emit(newEvent) } | |
} | |
protected fun updateUiState(update: (UiState<STATE>) -> UiState<STATE>) { | |
val newState = update(currentState) | |
if (newState != currentState) { | |
_uiState.value = newState | |
} | |
} | |
abstract fun handleEvent(event: EVENT) | |
... | |
} | |
// And how to pass info to ViewModel to handle events and update state | |
abstract class BaseFragment<STATE, EVENT : UiEvent, EFFECT : UiEffect, | |
VM : BaseViewModel<STATE, EVENT, EFFECT>, VDB : ViewDataBinding>( | |
@LayoutRes private val layoutId: Int, | |
vmKClass: KClass<VM> | |
) : Fragment() { | |
... | |
@InternalCoroutinesApi | |
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | |
super.onViewCreated(view, savedInstanceState) | |
with(viewModel) { | |
event | |
.onEach { handleEvent(it) } | |
.observeInLifecycle(viewLifecycleOwner) | |
uiState | |
.onEach { handleState(it) } | |
.observeInLifecycle(viewLifecycleOwner) | |
} | |
} | |
... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment