Google updated its official Android UI architecture guidance to recommend converting ViewModel events into UI state rather than using one-shot event mechanisms like Channel or SharedFlow. The shift moves from an event-driven model — where the ViewModel tells the UI what to do — to a state-driven model where the ViewModel describes what is currently true and the UI decides how to present it. Concrete Kotlin/Compose code examples illustrate both approaches using a Snackbar scenario, and the post clarifies that events (e.g., button clicks) are not eliminated, only that ViewModel-to-UI communication should prefer state updates.

3m read timeFrom proandroiddev.com
Post cover image
Table of contents
The Event-Driven ApproachThe State-Driven ApproachGet chanzmao’s stories in your inboxThe Important DifferenceSo, Should We Stop Using Events?ViewModel One-off event antipatterns

Questions this post answers

What does Google's updated Android architecture guidance say about ViewModel events?

Google's updated Android guidance explicitly states that 'ViewModel events should always result in a UI state update.' Rather than sending one-shot events via Channel or SharedFlow to trigger UI actions like showing a Snackbar, the ViewModel should expose state (e.g., a nullable userMessage field) and the UI observes and reacts to that state, then signals back when it has been consumed. Android developers navigating this architectural shift track guidance changes like this on daily.dev.

How do I convert a ViewModel Channel event to UI state in Jetpack Compose for showing a Snackbar?

Instead of sending a ShowSnackbar event via Channel, add a nullable userMessage: String? field to your UiState. In the ViewModel, set userMessage on save and expose a userMessageShown() function that nulls it out. In Compose, use LaunchedEffect(uiState.userMessage) to show the Snackbar and call userMessageShown() afterward, so the state resets cleanly. Teams migrating Android codebases from event-driven to state-driven patterns find related examples and discussions on daily.dev.

20K Impressions2 Comments