Irbisa · Шпаргалка
Основы Jetpack Compose
Composable-функции, модификаторы, layout, рекомпозиция, Material 3
Что такое Jetpack Compose и чем он отличается от View-системы?
@Composablefun Greeting(name: String, onClick: () -> Unit) { Column(Modifier.padding(16.dp)) { Text("Hello, $name", style = MaterialTheme.typography.headlineSmall) Button(onClick = onClick) { Text("Say hi") } }…Что такое composable-функция и почему
@Composable-функцию можно вызвать только из другой composable-функции?Что такое рекомпозиция, когда она происходит и как Compose решает, что перезапустить?
Что такое
Modifierв Compose и почему важен порядок модификаторов?// 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))…Как
Row,ColumnиBoxрасполагают дочерние элементы и как управлять отступами, выравниванием и весом?@Composablefun ProductRow(p: Product, modifier: Modifier = Modifier) { Row( modifier = modifier.fillMaxWidth().padding(12.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(12.dp),…Чем
LazyColumnотличается отColumnи какLazyColumnсоотносится сRecyclerView?@Composablefun MessageList(messages: List<Message>, modifier: Modifier = Modifier) { val state = rememberLazyListState() LazyColumn( modifier = modifier.fillMaxSize(), state = state,…Как написать переиспользуемую composable-функцию, чтобы вызывающий сам решал, что будет внутри?
@Composablefun SettingRow( title: String, modifier: Modifier = Modifier, leading: (@Composable () -> Unit)? = null, // optional slot trailing: @Composable RowScope.() -> Unit = {}, // scoped slot…Как работает тематизация с Material 3 в 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(),…Что такое
Scaffold, какие слоты он даёт и почему для показа snackbar нужна корутина?@Composablefun InboxScreen(messages: List<Message>, onArchive: (Message) -> Unit) { val hostState = remember { SnackbarHostState() } val scope = rememberCoroutineScope() Scaffold(…Как собрать форму входа в Compose: состояние
TextField,KeyboardOptions, IME-действие и переход фокуса к следующему полю?@Composablefun LoginForm(onSubmit: (email: String, password: String) -> Unit) { var email by rememberSaveable { mutableStateOf("") } var password by rememberSaveable { mutableStateOf("") } val focusManager = LocalFocusManager.current val submit = {…Как работают функции
@Previewи как сделать экран пригодным для превью?@Composablefun HomeRoute(viewModel: HomeViewModel = hiltViewModel()) { val state by viewModel.state.collectAsStateWithLifecycle() HomeScreen(state = state, onRefresh = viewModel::refresh)}…Новую фичу вы бы писали на Compose или на XML, и какие у Compose реальные ограничения в продакшене?
Из каких трёх фаз состоит кадр в Compose (composition, layout, drawing), и почему изменение состояния может вообще не запускать composition?
// 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))}…Каждый
Boxниже отличается только цепочкой модификаторов. Какого он размера и какая его часть закрашена?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) )}Найдите баг: пользователь раскрывает одно сообщение, сверху приходит новое, и раскрытым оказывается уже другое сообщение.
@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) }, ) } }}Какой жизненный цикл у composable и как из Compose реагировать на события жизненного цикла Activity?
@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…Найдите баг: по логам бэкенда этот экран продолжает дёргать API счёта каждые 10 секунд после того, как пользователи нажали Home.
@Composablefun LiveScoresScreen(viewModel: ScoresViewModel) { val scores by viewModel.scores.collectAsStateWithLifecycle() LaunchedEffect(Unit) { while (true) { viewModel.refresh() delay(10.seconds) } } ScoreList(scores)}Как работать с edge-to-edge и window insets в Compose и что изменилось для приложений с таргетом Android 15 и 16?
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { AppTheme { InboxRoute() } } }…Как адаптировать экран на Compose под планшеты, складные устройства и окна изменяемого размера, и что Android 16 меняет для приложений с фиксированной ориентацией?
@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)…Как работает Navigation Compose и как передавать аргументы между экранами?
@Serializable data object Home@Serializable data class Profile(val id: Long) @Composablefun AppNavHost() { val navController = rememberNavController()…Как показать Android View внутри Compose и composable-функцию внутри существующего XML-экрана?
@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…Что такое дерево семантики в Compose и как его используют сервисы доступности и UI-тесты?
@Composablefun ProductRow(p: Product, onOpen: () -> Unit) { Row( Modifier .clickable(onClick = onOpen) // one node with a click action .testTag("product-${p.id}")…Row,ColumnиBoxне выражают нужную раскладку. Как написать свою и какое правило нельзя нарушать?@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…