Android Jetpack Compose Excellence 🎨
Expert guidance for building modern, high-performance Android UI with Jetpack Compose.
⚡ When to Use
- New Feature UI: Starting a new screen or custom component.
- UI Refactoring: Moving from XML to Compose or legacy Compose to modern patterns.
- Theming: Implementing Material 3, Dark Mode, or Custom Design Systems.
- Performance Fixes: Debugging recomposition issues or laggy lists.
- Animations: Adding smooth transitions and micro-interactions.
🏗️ Core Principles
1. State Management (Hoisting)
- Rule: Composables should be stateless where possible. Hoist state to the caller.
- Bad:
@Composable fun SearchBar() { val text = remember { mutableStateOf("") } // Local state in reusable component TextField(value = text.value, text.value = it }) } - Good:
@Composable fun SearchBar( query: String, onQueryChange: (String) -> Unit ) { TextField(value = query, }
2. Slot API Pattern
- For complex components, use "Slots" (content parameters) to increase flexibility.
@Composable fun AppHeader( title: @Composable () -> Unit, actions: @Composable RowScope.() -> Unit = {} ) { ... }
3. Material 3 (M3)
- Always prefer
androidx.compose.material3components. - Use
ColorScheme,Typography, andShapesfrom the theme.
🚀 Performance Checklist
- Lambda Stability: Method references (
::onAction) or bound lambdas(val -> action(val))are safer for stability than capturing unstable variables. - derivedStateOf: Use when a state depends on another state that changes frequently (e.g., scroll position).
- remember(key): Correctly keying
rememberblocks to avoid stale data. - Lists: Use
LazyColumn/LazyRowand ALWAYS provide akeytoitems.
🎨 Animations
AnimatedVisibility: For simple appear/disappear.animateColorAsState: For smooth color changes.Transition: For complex, multi-state animations.Lottie: Uselottie-composefor complex vector animations.
🧪 Testing and Previews
- Previews: Use
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)for dark mode testing. - Multi-device Previews: Use
@PreviewScreenSizesand@PreviewFontScales. - UI Testing: Use
createComposeRule()andonNodeWithTag().