Android ViewModel & State Management

SkillMedia

Guides your agent to write Android ViewModel code using StateFlow for UI state and SharedFlow for one-off events.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Android ViewModel & State Management skill

About this capability

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

What this skill tells your AI

The instructions your AI receives, as published by maxrave-dev/simpmusic in .claude/skills/android-viewmodel/SKILL.md and read by ahel’s review.

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.
    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.
    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.
    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.

Signals

GitHub stars
11k
Forks
584
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
android-viewmodel
Source
github.com/maxrave-dev/simpmusic