Free course · 11 lessons · Intermediate

Android with Kotlin and Jetpack Compose

Build modern Android apps with Kotlin and Jetpack Compose: composable screens, layouts and lists, state and side effects, ViewModels with StateFlow, Navigation 3, networking with Retrofit and kotlinx.serialization, offline-first data with Room, dependency injection with Hilt, background work with WorkManager, testing, and releasing on Google Play. The UI code is shown in full, and the logic in every lesson is compiled and run.

Start the course

1. Compose Foundations: Screens, Layout, Lists and State

Create an Android app with Kotlin and Jetpack Compose, build screens from composable functions, lay them out with modifiers, show long lists with LazyColumn, and manage state so the UI always matches your data.

  1. Your First Android App with Jetpack Compose — Create a project in Android Studio, understand MainActivity, setContent and composable functions, preview UI without a device, and run the app on an emulator or your phone.
  2. Layouts, Modifiers and Material 3 Theming — Arrange UI with Column, Row and Box, size and space it with modifiers (where order matters), theme it with Material 3, and adapt the layout to phones, foldables and tablets.
  3. Long Lists with LazyColumn — Show thousands of items efficiently with LazyColumn and LazyVerticalGrid, give items stable keys, add sticky section headers, and avoid the mistakes that make lists janky.
  4. State, State Hoisting and Side Effects — Where state should live in Compose: remember and rememberSaveable, state hoisting into stateless composables, derived state, and running side effects safely with LaunchedEffect.

2. Architecture and Data: ViewModels, Navigation, Networking and Offline

Structure the app the way Google recommends: a ViewModel exposing UI state as StateFlow, type-safe navigation with Navigation 3, a repository that talks to a REST API with Retrofit and kotlinx.serialization, and an offline-first cache with Room.

  1. ViewModels and UI State with StateFlow — Move screen logic into a ViewModel, model the screen as one immutable UI state, expose it as a StateFlow, and collect it safely in Compose with collectAsStateWithLifecycle.
  2. Navigation with Navigation 3 — Move between screens with Navigation 3: a back stack you own as a list of keys, NavDisplay to show it, typed keys with arguments, and back handling.
  3. Networking with Retrofit, kotlinx.serialization and Repositories — Call a REST API with Retrofit and kotlinx.serialization, hide it behind a repository, map errors to messages the UI can show, and retry with exponential backoff.
  4. Room and Offline-First Data — Store data on the device with Room, observe it as a Flow, and build an offline-first repository: the UI reads the local database, and sync keeps it up to date with the server.

3. Production: Dependency Injection, Background Work, Testing and Release

Wire the app together with Hilt, schedule reliable background sync with WorkManager and handle runtime permissions, test ViewModels and Compose UI, and ship a fast, small release build through Google Play.

  1. Dependency Injection with Hilt — Why dependency injection matters for testable apps, and how Hilt provides repositories, API clients and databases to ViewModels with a few annotations.
  2. Background Work, Notifications and Runtime Permissions — Run reliable background sync with WorkManager (constraints, backoff, unique work), ask for runtime permissions such as notifications at the right moment, and respect Android's background limits.
  3. Testing, Performance and Releasing on Google Play — Test ViewModels with coroutines test tools and Compose UI with semantics, keep the app fast with baseline profiles and R8, and ship through Play Console testing tracks with staged rollouts.

Was this page helpful?