Awesome-android-agent-skills android-viewmodel
Best practices for implementing Android ViewModels, specifically focused on StateFlow for UI state and SharedFlow for one-off events.
install
source · Clone the upstream repo
git clone https://github.com/new-silvermoon/awesome-android-agent-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/new-silvermoon/awesome-android-agent-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.github/skills/architecture/android-viewmodel" ~/.claude/skills/new-silvermoon-awesome-android-agent-skills-android-viewmodel && rm -rf "$T"
manifest:
.github/skills/architecture/android-viewmodel/SKILL.mdsource content
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
backing a privateStateFlow
.MutableStateFlowprivate val _uiState = MutableStateFlow<UiState>(UiState.Loading) val uiState: StateFlow<UiState> = _uiState.asStateFlow() - Updates: Update state using
for thread safety..update { oldState -> ... }
2. One-Off Events (SharedFlow)
- What: Transient events like "Show Toast", "Navigate to Screen", "Show Snackbar".
- Type:
.SharedFlow<UiEvent> - Configuration: Must use
to prevent events from re-triggering on screen rotation.replay = 0private val _uiEvent = MutableSharedFlow<UiEvent>(replay = 0) val uiEvent: SharedFlow<UiEvent> = _uiEvent.asSharedFlow() - Sending: Use
(suspend) or.emit(event)
..tryEmit(event)
3. Collecting in UI
- Compose: Use
forcollectAsStateWithLifecycle()
.StateFlow
Forval state by viewModel.uiState.collectAsStateWithLifecycle()
, useSharedFlow
withLaunchedEffect
.LocalLifecycleOwner - Views (XML): Use
within a coroutine.repeatOnLifecycle(Lifecycle.State.STARTED)
4. Scope
- Use
for all coroutines started by the ViewModel.viewModelScope - Ideally, specific operations should be delegated to UseCases or Repositories.