Irbisa · Cheatsheet
Jetpack Compose Fundamentals
Composable functions, modifiers, layout, recomposition, Material 3
What is Jetpack Compose, and how is it different from the View system?
@Composablefun Greeting(name: String, onClick: () -> Unit) { Column(Modifier.padding(16.dp)) { Text("Hello, $name", style = MaterialTheme.typography.headlineSmall) Button(onClick = onClick) { Text("Say hi") } }…What is a composable function, and why can a
@Composablefunction only be called from another composable?What is recomposition, when does it happen, and how does Compose decide what to re-run?
What is a
Modifierin Compose, and why does the order of modifiers matter?// Red covers only the inner area; the 16dp padding stays transparentText("A", Modifier.padding(16.dp).background(Color.Red)) // Red covers the padding as wellText("B", Modifier.background(Color.Red).padding(16.dp))…How do
Row,ColumnandBoxlay out their children, and how do you control spacing, alignment and weight?@Composablefun ProductRow(p: Product, modifier: Modifier = Modifier) { Row( modifier = modifier.fillMaxWidth().padding(12.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(12.dp),…What is the difference between
LazyColumnandColumn, and how doesLazyColumncompare toRecyclerView?@Composablefun MessageList(messages: List<Message>, modifier: Modifier = Modifier) { val state = rememberLazyListState() LazyColumn( modifier = modifier.fillMaxSize(), state = state,…How do you write a reusable composable that lets the caller decide what goes inside it?
@Composablefun SettingRow( title: String, modifier: Modifier = Modifier, leading: (@Composable () -> Unit)? = null, // optional slot trailing: @Composable RowScope.() -> Unit = {}, // scoped slot…How does theming work with Material 3 in Compose?
private val LightColors = lightColorScheme(primary = Color(0xFF1565C0), onPrimary = Color.White)private val DarkColors = darkColorScheme(primary = Color(0xFF90CAF9), onPrimary = Color(0xFF003258)) @Composablefun AppTheme( dark: Boolean = isSystemInDarkTheme(),…What is
Scaffold, which slots does it offer, and why does showing a snackbar need a coroutine?@Composablefun InboxScreen(messages: List<Message>, onArchive: (Message) -> Unit) { val hostState = remember { SnackbarHostState() } val scope = rememberCoroutineScope() Scaffold(…How do you build a login form in Compose:
TextFieldstate,KeyboardOptions, the IME action, and moving focus to the next field?@Composablefun LoginForm(onSubmit: (email: String, password: String) -> Unit) { var email by rememberSaveable { mutableStateOf("") } var password by rememberSaveable { mutableStateOf("") } val focusManager = LocalFocusManager.current val submit = {…How do
@Previewfunctions work, and how do you keep a screen previewable?@Composablefun HomeRoute(viewModel: HomeViewModel = hiltViewModel()) { val state by viewModel.state.collectAsStateWithLifecycle() HomeScreen(state = state, onRefresh = viewModel::refresh)}…Would you build a new feature in Compose or in XML, and what are Compose's real limitations in production?
What are the three phases of a Compose frame (composition, layout, drawing), and why can a state change skip composition entirely?
// read in composition: every animation frame recomposes DotSlow before it is redrawn@Composablefun DotSlow(selected: Boolean) { val color by animateColorAsState(if (selected) Color.Red else Color.Gray, label = "dot") Box(Modifier.size(24.dp).background(color))}…Each
Boxbelow differs only in its modifier chain. How big is each one, and how much of it is coloured?Column { // A Box(Modifier.size(100.dp).size(50.dp).background(Color.Red)) // B Box(Modifier.size(50.dp).padding(10.dp).background(Color.Green)) // C Box(Modifier.padding(10.dp).size(50.dp).background(Color.Blue)) // D Box( Modifier.width(200.dp).requiredWidth(80.dp) .height(40.dp).background(Color.Gray) )}Find the bug: a user expands one message, a new message arrives at the top, and now a different message is shown expanded.
@Composablefun InboxList(messages: List<Message>, onOpen: (Message) -> Unit) { LazyColumn { items(messages) { message -> var expanded by remember { mutableStateOf(false) } MessageRow( message = message, expanded = expanded, onToggle = { expanded = !expanded }, onOpen = { onOpen(message) }, ) } }}What is the lifecycle of a composable, and how do you react to the Activity's lifecycle events from Compose?
@Composablefun MapScreen(viewModel: MapViewModel) { // Stops collecting when the app goes below STARTED val state by viewModel.state.collectAsStateWithLifecycle() // Start on ON_START, stop on ON_STOP or when leaving the composition…Find the bug: backend logs show this screen still calling the scores API every 10 seconds after users press Home.
@Composablefun LiveScoresScreen(viewModel: ScoresViewModel) { val scores by viewModel.scores.collectAsStateWithLifecycle() LaunchedEffect(Unit) { while (true) { viewModel.refresh() delay(10.seconds) } } ScoreList(scores)}How do you handle edge-to-edge and window insets in Compose, and what changed for apps targeting Android 15 and 16?
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { AppTheme { InboxRoute() } } }…How do you adapt a Compose screen to tablets, foldables and resizable windows, and what does Android 16 change for apps that lock orientation?
@Composablefun MailApp(tabs: List<Tab>, mails: List<Mail>) { var current by rememberSaveable { mutableIntStateOf(0) } val listState = rememberLazyListState() // above the branch: an unfold keeps the scroll val wide = currentWindowAdaptiveInfoV2().windowSizeClass .isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND)…How does Navigation Compose work, and how do you pass arguments between screens?
@Serializable data object Home@Serializable data class Profile(val id: Long) @Composablefun AppNavHost() { val navController = rememberNavController()…How do you show an Android View inside Compose, and a composable inside an existing XML screen?
@Composablefun WebPage(url: String, modifier: Modifier = Modifier) { AndroidView( modifier = modifier, factory = { context -> WebView(context) }, // runs once update = { view -> view.loadUrl(url) }, // re-runs when url changes…What is the semantics tree in Compose, and how do accessibility services and UI tests use it?
@Composablefun ProductRow(p: Product, onOpen: () -> Unit) { Row( Modifier .clickable(onClick = onOpen) // one node with a click action .testTag("product-${p.id}")…Row,ColumnandBoxcannot express the layout you need. How do you write your own, and what rule must you respect?@Composablefun TwoColumnGrid(modifier: Modifier = Modifier, content: @Composable () -> Unit) { Layout(content = content, modifier = modifier) { measurables, constraints -> val columnWidth = constraints.maxWidth / 2 val childConstraints = constraints.copy(minWidth = 0, maxWidth = columnWidth) val placeables = measurables.map { it.measure(childConstraints) } // once each…