androidengineers.Book a session

Architecture & Data

MVVM Architecture Pattern

article40 minHard

MVVM stands for Model View ViewModel. It is a common Android architecture pattern that separates UI from business logic.

The goal is simple: composables display state and send events, while the ViewModel prepares state and coordinates work.

Responsibilities

LayerResponsibility
ViewRender UI and send user events
ViewModelHold UI state and handle screen logic
ModelData classes, repositories, APIs, database

Basic UI State

data class LoginUiState(
    val email: String = "",
    val password: String = "",
    val isLoading: Boolean = false,
    val error: String? = null
)

The UI reads this state.

@Composable
fun LoginScreen(
    state: LoginUiState,
    onEmailChange: (String) -> Unit,
    onSubmit: () -> Unit
) {
    TextField(value = state.email, onValueChange = onEmailChange)
    Button(onClick = onSubmit, enabled = !state.isLoading) {
        Text("Login")
    }
}

ViewModel

The recommended approach is to expose state as a StateFlow. It survives configuration changes and works well with lifecycle-aware collection.

class LoginViewModel : ViewModel() {
    private val _state = MutableStateFlow(LoginUiState())
    val state: StateFlow<LoginUiState> = _state.asStateFlow()

    fun onEmailChange(email: String) {
        _state.update { it.copy(email = email) }
    }

    fun submit() {
        _state.update { it.copy(isLoading = true, error = null) }
        viewModelScope.launch {
            try {
                // call repository
            } catch (e: Exception) {
                _state.update { it.copy(isLoading = false, error = e.message) }
            }
        }
    }
}

In the composable, collect the state with collectAsStateWithLifecycle. This stops collection when the screen is not visible, which saves battery.

@Composable
fun LoginRoute(viewModel: LoginViewModel = viewModel()) {
    val state by viewModel.state.collectAsStateWithLifecycle()

    LoginScreen(
        state = state,
        onEmailChange = viewModel::onEmailChange,
        onSubmit = viewModel::submit
    )
}

The ViewModel exposes state and functions. The UI does not know where data comes from.

Why MVVM Helps

MVVM makes code easier to test because business decisions live outside UI. It also avoids huge Activity or composable files.

Practice

Build a todo input screen. Create TodoUiState, a TodoViewModel, and a stateless composable that receives state and callbacks.

Summary

MVVM keeps UI simple and moves screen logic into ViewModels. Use StateFlow with collectAsStateWithLifecycle for production-grade state observation. For junior Android developers, this is the first major step toward professional app architecture.

YOUR LEARNING JOURNEY

0 of 22 available lessons completed

Progress saved in this browser. No account needed.
MVVM Architecture Pattern | Junior Android Developer | Android Engineers