Skip to main content

android-viewmodel

Best practices for implementing Android ViewModels, specifically focused on StateFlow for UI state and SharedFlow for one-off events.

Source facts

Repository
maxrave-dev/SimpMusic
Last source activity
March 5, 2026 at 02:43
Detected SKILL.md language
English
Stars
13,045
Forks
734

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
android-viewmodel
description
Best practices for implementing Android ViewModels, specifically focused on StateFlow for UI state and SharedFlow for one-off events.
# Android ViewModel & State Management ## Instructions Use `ViewModel` to hold state and business logic. It must outlive configuration changes. ### 1. UI State (StateFlow) * **What**: Represents the persistent state of the UI (e.g., `Loading`, `Success(data)`, `Error`). * **Type**: `StateFlow<UiState>`. * **Initialization**: Must have an initial value. * **Exposure**: Expose as a read-only `StateFlow` backing a private `MutableStateFlow`. ```kotlin private val _uiState = MutableStateFlow<UiState>(UiState.Loading) val uiState: StateFlow<UiState> = _uiState.asStateFlow() ``` * **Updates**: Update state using `.update { oldState -> ... }` for thread safety. ### 2. One-Off Events (SharedFlow) * **What**: Transient events like "Show Toast", "Navigate to Screen", "Show Snackbar". * **Type**: `SharedFlow<UiEvent>`. * **Configuration**: Must use `replay = 0` to prevent events from re-triggering on screen rotation. ```kotlin private val _uiEvent = MutableSharedFlow<UiEvent>(replay = 0) val uiEvent: SharedFlow<UiEvent> = _uiEvent.asSharedFlow() ``` * **Sending**: Use `.emit(event)` (suspend) or `.tryEmit(event)`. ### 3. Collecting in UI * **Compose**: Use `collectAsStateWithLifecycle()` for `StateFlow`. ```kotlin val state by viewModel.uiState.collectAsStateWithLifecycle() ``` For `SharedFlow`, use `LaunchedEffect` with `LocalLifecycleOwner`. * **Views (XML)**: Use `repeatOnLifecycle(Lifecycle.State.STARTED)` within a coroutine. ### 4. Scope * Use `viewModelScope` for all coroutines started by the ViewModel. * Ideally, specific operations should be delegated to UseCases or Repositories.
View on GitHub