Skip to main content

android-compose-components

Complete catalog of Android Jetpack Compose and Material Design 3 components. Covers M3 Expressive (2025), gesture system, graphics/drawing, navigation patterns, theming, and mapping guidance for Crystal cross-platform UI integration via JNI.

Jump to install

Source facts

Repository
amberframework/asset_pipeline
Last source activity
April 15, 2026 at 13:35
Detected SKILL.md language
English
Stars
5
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
android-compose-components
description
Complete catalog of Android Jetpack Compose and Material Design 3 components. Covers M3 Expressive (2025), gesture system, graphics/drawing, navigation patterns, theming, and mapping guidance for Crystal cross-platform UI integration via JNI.
user-invocable
true
allowed-tools
Read, Write, Edit, Glob, Grep, Bash, WebSearch, WebFetch
version
1.0.0
# Android Jetpack Compose / Material 3 Components Reference This document is the authoritative reference for Android Jetpack Compose and Material Design 3 UI components as of 2025 (compose-material3 1.4.0 stable, 1.5.x alpha series). It covers Material 3 Expressive, the full gesture system, Canvas/graphics APIs, adaptive navigation, theming tokens, and platform-specific Android APIs. It provides implementation priority guidance for the asset_pipeline Crystal library's `Android::Renderer` (JNI bridge). The asset_pipeline maps Crystal `UI::View` types to native Android elements at compile time. The `Android::Renderer` (in `src/ui/renderers/android_renderer.cr`) calls through the JNI bridge (`jni_bridge.c`) to Kotlin/Java, which creates the actual View or Composable objects. The JNI collection bridge (`src/ui/native/jni_collections.cr`) provides typed wrappers for JNI references, ViewGroup batch operations, and string marshaling. --- ## 1. Overview ### Material Design 3 and M3 Expressive Material Design 3 (M3) is the current Google design system, launched alongside Android 12 (Material You). As of 2025 the system has evolved into M3 Expressive, announced at Google I/O 2025, which adds: - Five new component families: ButtonGroup, SplitButtonLayout, FloatingActionButtonMenu, LoadingIndicator/WavyProgressIndicator, and Floating Toolbars - 35 new shape definitions and shape-morphing animations - A physics-based spring motion system replacing fixed easing curves - Enhanced typography expressiveness - Research backed by 46 studies and 18,000+ participants The Jetpack Compose implementation ships in `androidx.compose.material3` (latest stable 1.4.0, released September 24 2025). Experimental and expressive APIs continue in the 1.5.x alpha series. ### Jetpack Compose vs Traditional Android Views | Aspect | Jetpack Compose | Traditional Android Views | |--------|----------------|--------------------------| | Paradigm | Declarative (describe what, not how) | Imperative (XML + Java/Kotlin mutations) | | State | `State<T>`, `MutableState<T>`, `remember {}` | ViewModel + LiveData/StateFlow observers | | Layout | Compose layout pass (intrinsics-based) | Measure/layout/draw pass on View hierarchy | | Thread | Main thread, coroutines for side effects | Main thread for UI; background via Handler | | Styling | Modifier chains, MaterialTheme | XML attributes, style resources, themes | | Crystal JNI | Lower priority — hard to drive from native | Higher priority — `jobject` ViewGroup refs | ### Crystal Integration: JNI Bridge Pattern ``` Crystal UI::View tree | v Android::Renderer (src/ui/renderers/android_renderer.cr) visit(label) / visit(button) / ... | v [Crystal -> C via @[Link] fun declarations] jni_bridge.c (C wrapper functions) | v [C -> JVM via JNIEnv* calls] Kotlin/Java Activity or Fragment - Inflates Views or creates Composables - Returns jobject back to C | v [back to Crystal] NativeHandle (UI::JNI.global(env, local_ref)) stored in NativeView node ``` The JNI collection bridge (`src/ui/native/jni_collections.cr`) provides: - `UI::JNI::JString` — Crystal String <-> jstring marshaling - `UI::JNI::ObjectArray` — Crystal Array <-> jobjectArray - `UI::JNI::ArrayList` — Crystal Array <-> java.util.ArrayList - `UI::JNI.viewgroup_add_views(env, parent, children)` — batch addView() - `UI::JNI.local_frame(env, capacity)` — scoped local reference tables **Critical JNI rule:** Local refs are only valid within the current native method call. Use `UI::JNI.global(env, local_ref)` to promote any View reference that Crystal must hold past the return boundary, then `NativeHandle` tracks the lifetime. ### API Level Requirements Summary | Feature | Min API | |---------|---------| | All Compose basics | 21 (Android 5.0) | | Dynamic Color (Material You) | 31 (Android 12) | | RenderEffect / blur | 31 (Android 12) | | RuntimeShader / AGSL | 33 (Android 13) | | Predictive back gesture | 34 (Android 14) | | Compose BOM 2024+ | 21 | | WideNavigationRail | 21 (M3 Expressive, lib-based) | | FloatingActionButtonMenu | 21 (M3 Expressive, lib-based) | | WavyLinearProgressIndicator | 21 (M3 Expressive, lib-based) | | Picture-in-Picture | 26 (Android 8.0) | | Glance Widgets | 23 (Android 6.0) | --- ## 2. Material 3 Components by Category All components require: ```kotlin implementation("androidx.compose.material3:material3:1.4.0") ``` Experimental APIs require `@OptIn(ExperimentalMaterial3Api::class)`. Expressive APIs (1.5.x alpha) additionally require `@OptIn(ExperimentalMaterial3ExpressiveApi::class)`. --- ### 2.1 Buttons and FABs #### Standard Buttons | Compose Function | Emphasis | Traditional View | Crystal UI::View Equiv. | Priority | |-----------------|----------|-----------------|------------------------|----------| | `Button` | High — filled, primary color | `MaterialButton` | `UI::Button` (maps here) | P0 (done) | | `FilledButton` | High — alias for Button | `MaterialButton` | Same as Button | P0 | | `ElevatedButton` | Medium — elevated surface | `MaterialButton` (elevation style) | — | P1 | | `FilledTonalButton` | Medium — secondary container fill | `MaterialButton` (tonal style) | — | P1 | | `OutlinedButton` | Low — bordered, transparent fill | `MaterialButton` (outlined style) | — | P1 | | `TextButton` | Lowest — text only | `MaterialButton` (text style) | — | P2 | All button parameters: ```kotlin Button( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, shape: Shape = ButtonDefaults.shape, // RoundedCornerShape(50%) by default colors: ButtonColors = ButtonDefaults.buttonColors(), elevation: ButtonElevation? = ButtonDefaults.buttonElevation(), border: BorderStroke? = null, contentPadding: PaddingValues = ButtonDefaults.ContentPadding, interactionSource: MutableInteractionSource? = null, content: @Composable RowScope.() -> Unit ) ``` #### Icon Buttons | Compose Function | Traditional View | Priority | |-----------------|-----------------|----------| | `IconButton` | `ImageButton` | P1 | | `FilledIconButton` | `MaterialButton` (icon, filled) | P2 | | `FilledTonalIconButton` | `MaterialButton` (icon, tonal) | P2 | | `OutlinedIconButton` | `MaterialButton` (icon, outlined) | P2 | | `IconToggleButton` | `ImageButton` + toggle state | P2 | #### Floating Action Buttons (FABs) | Compose Function | Size | Traditional View | Priority | |-----------------|------|-----------------|----------| | `FloatingActionButton` | Standard (56dp) | `FloatingActionButton` | P1 | | `SmallFloatingActionButton` | Small (40dp) | `FloatingActionButton` (mini) | P2 | | `LargeFloatingActionButton` | Large (96dp) | `FloatingActionButton` (large) | P2 | | `ExtendedFloatingActionButton` | Pill with text | `ExtendedFloatingActionButton` | P2 | FAB parameters: ```kotlin FloatingActionButton( onClick: () -> Unit, modifier: Modifier = Modifier, shape: Shape = FloatingActionButtonDefaults.shape, containerColor: Color = FloatingActionButtonDefaults.containerColor, contentColor: Color = contentColorFor(containerColor), elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(), interactionSource: MutableInteractionSource? = null, content: @Composable () -> Unit ) ``` #### NEW: M3 Expressive Button Components (1.4.x / 1.5.x-alpha) | Compose Function | Description | Traditional View Equiv. | Priority | |-----------------|-------------|------------------------|----------| | `ButtonGroup` | Horizontal or vertical group of semantically related buttons with connected styling | `LinearLayout` of `MaterialButton` | P2 | | `SplitButtonLayout` | Two-zone button: action zone + dropdown trigger zone | Custom compound `MaterialButton` | P2 | | `FloatingActionButtonMenu` | FAB that expands into a menu of secondary actions | Custom `CoordinatorLayout` pattern | P2 | | `ToggleFloatingActionButton` | FAB with toggled (expanded/collapsed) state, used as anchor for FABMenu | `FloatingActionButton` | P2 | | `FloatingActionButtonMenuItem` | Individual item inside a FABMenu | `MaterialButton` in overlay | P2 | ```kotlin // ButtonGroup usage (M3 Expressive) ButtonGroup( modifier: Modifier = Modifier, horizontalArrangement: Arrangement.Horizontal = ButtonGroupDefaults.horizontalArrangement, verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, content: @Composable ButtonGroupScope.() -> Unit ) // Inside ButtonGroupScope, use Modifier.align() per-button // FloatingActionButtonMenu usage FloatingActionButtonMenu( expanded: Boolean, button: @Composable () -> Unit, // Typically a ToggleFloatingActionButton modifier: Modifier = Modifier, content: @Composable FloatingActionButtonMenuScope.() -> Unit ) { FloatingActionButtonMenuItem( onClick = { /* action */ }, icon = { Icon(Icons.Default.Share, contentDescription = null) }, text = { Text("Share") } ) } ``` --- ### 2.2 Selection Controls #### Checkbox | Compose Function | Traditional View | Parameters | Priority | |-----------------|-----------------|------------|----------| | `Checkbox` | `CheckBox` | `checked`, `onCheckedChange`, `enabled`, `colors` | P1 | | `TriStateCheckbox` | `CheckBox` (partial state) | `state: ToggleableState`, `onClick`, `enabled`, `colors` | P2 | ```kotlin Checkbox( checked: Boolean, onCheckedChange: ((Boolean) -> Unit)?, modifier: Modifier = Modifier, enabled: Boolean = true, colors: CheckboxColors = CheckboxDefaults.colors(), interactionSource: MutableInteractionSource? = null ) ``` #### RadioButton | Compose Function | Traditional View | Priority | |-----------------|-----------------|----------| | `RadioButton` | `RadioButton` | P1 | RadioButton has no built-in group; you track selection state in the parent composable. Traditional equivalent for a group: `RadioGroup` containing `RadioButton` views. ```kotlin RadioButton( selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier = Modifier, enabled: Boolean = true, colors: RadioButtonColors = RadioButtonDefaults.colors() ) ``` #### Switch | Compose Function | Traditional View | Crystal UI::View Equiv. | Priority | |-----------------|-----------------|------------------------|----------| | `Switch` | `SwitchCompat` / `MaterialSwitch` | — | P1 | ```kotlin Switch( checked: Boolean, onCheckedChange: ((Boolean) -> Unit)?, modifier: Modifier = Modifier, thumbContent: (@Composable () -> Unit)? = null, // Icon inside thumb enabled: Boolean = true, colors: SwitchColors = SwitchDefaults.colors(), interactionSource: MutableInteractionSource? = null ) ``` #### Chips All chips require `@OptIn(ExperimentalMaterial3Api::class)`. | Compose Function | Use Case | Traditional View | Priority |
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub