Skip to content
Development
Skill

/android-ux

Use when designing or reviewing Android UI — applies Material Design 3 UX principles covering touch targets, spacing, navigation patterns, accessibility, animation timing, and platform conventions. Includes an M3 compliance audit that scores screens across 10 categories.

BOOST
From plugin
android-skills
16221 skills
Install
$ npx -y skills add rcosteira79/android-skills --skill android-ux --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/android-ux

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when designing or reviewing Android UI — applies Material Design 3 UX principles covering touch targets, spacing, navigation patterns, accessibility, animation timing, and platform conventions. Includes an M3 compliance audit that scores screens across 10 categories.

SKILL.md

android-ux.SKILL.md
name: android-ux
description: Use when designing or reviewing Android UI — applies Material Design 3 UX principles covering touch targets, spacing, navigation patterns, accessibility, animation timing, and platform conventions. Includes an M3 compliance audit that scores screens across 10 categories. Complements the compose skill with design-level decisions.

Android UX

This reference covers the non-obvious platform facts and **reviewing** an existing screen for M3 compliance, not the basics of building M3-correct UI.

Non-obvious platform facts

Foldable postures

Foldables introduce postures beyond window size classes. Detect them with `WindowInfoTracker` + `FoldingFeature` (Jetpack WindowManager), and **never place interactive content or critical information across the hinge**.

| Posture | Detection | Layout behavior | |---|---|---| | Flat (unfolded) | no folding feature | Treat as Medium/Expanded by width | | Half-opened, horizontal fold (tabletop) | `HALF_OPENED` + `Orientation.HORIZONTAL` | Content top half, controls bottom half | | Half-opened, vertical fold (book) | `HALF_OPENED` + `Orientation.VERTICAL` | List left, detail right | | Folded (cover screen) | — | Treat as Compact |

@Composable
fun FoldAwareLayout() {
    val context = LocalContext.current
    val layoutInfo by WindowInfoTracker.getOrCreate(context)
        .windowLayoutInfo(context)  // accepts @UiContext — Activity, InputMethodService, or createWindowContext()
        .collectAsStateWithLifecycle(initialValue = WindowLayoutInfo(emptyList()))

    val fold = layoutInfo.displayFeatures.filterIsInstance<FoldingFeature>().firstOrNull()
    when {
        fold?.state == FoldingFeature.State.HALF_OPENED ->
            if (fold.orientation == FoldingFeature.Orientation.HORIZONTAL) TabletopLayout() else BookLayout()
        else -> StandardAdaptiveLayout()  // by window size class
    }
}

M3 contrast levels (user-controlled contrast)

Compose's `dynamicLightColorScheme` / `dynamicDarkColorScheme` read the system contrast setting automatically (SDK 34+) and expose **no** contrast parameter. To offer *in-app* contrast control (Standard 0.0 / Medium 0.5 / High 1.0 tonal distance), build the scheme from `Hct` + `SchemeContent`:

// com.google.android.material:material (MDC-Android), package com.google.android.material.color.utilities
// Marked @RestrictTo(LIBRARY_GROUP) — internal API, may change between versions; re-check on version bumps.
val hct = Hct.fromInt(0xFF6750A4.toInt())
val scheme = SchemeContent(hct, /* isDark = */ false, /* contrastLevel = */ 1.0)
val colorScheme = lightColorScheme(
    primary = Color(scheme.primary),
    onPrimary = Color(scheme.onPrimary),
    // ... map remaining roles
)

For multiplatform or a stable public API, `com.materialkolor:material-color-utilities` is a KMP alternative.

Motion: duration tokens + reduced motion

Pair M3's duration ladder with easing (`short*` → `FastOutSlowIn`; `medium*` → `Emphasized(De/Ac)celerate`; `long*`/`extraLong*` → `Emphasized`) rather than arbitrary millis. Reach for `MotionScheme` (Compose M3 1.4+) where available; otherwise hold durations at one source of truth in the theme.

| Token group | Range | Typical use | |---|---|---| | `short1`…`short4` | 50–200ms | Micro-interactions, state changes (ripple, selection, switch) | | `medium1`…`medium4` | 250–400ms | Standard transitions (screen enter/exit, expansion, reveal) | | `long1`…`long4` | 450–600ms | Container transforms, fade-through between large surfaces | | `extraLong1`…`extraLong4` | 700–1000ms | Shared-element / hero transitions on tablets/foldables |

Animations must be interruptible and never block input. **Respect reduced motion** — Compose has no built-in `LocalReducedMotion`, so read `ANIMATOR_DURATION_SCALE` and provide one:

val LocalReducedMotion = staticCompositionLocalOf { false }

@Composable
fun AppTheme(content: @Composable () -> Unit) {
    val context = LocalContext.current
    val reduceMotion = remember {
        Settings.Global.getFloat(context.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f) == 0f
    }
    CompositionLocalProvider(LocalReducedMotion provides reduceMotion) { MaterialTheme { content() } }
}

// at the call site
AnimatedVisibility(
    visible = isVisible,
    enter = if (LocalReducedMotion.current) EnterTransition.None else fadeIn() + slideInVertically(),
) { Content() }

(`staticCompositionLocalOf` + keyless `remember` read the setting once per Activity; for live updates switch to `compositionLocalOf` + a `ContentObserver` on `ANIMATOR_DURATION_SCALE`.)

---

M3 Compliance Audit

Use this when **reviewing** a screen or feature for Material Design 3 compliance — the part that's easy to skip from memory. Score each category **Pass / Partial / Fail**, then fix any Partial/Fail before shipping.

1. Color tokens

  • All colors reference `MaterialTheme.colorScheme` roles — no hardcoded hex/ARGB.
  • Correct role usage: `primary` for key actions, `secondary`/`tertiary` for less prominent / accents, `error` for errors; `on*` paired correctly; layered surfaces via `surfaceContainerLow/High`, not arbitrary grays.
  • Outlines: `outline` for interactive boundaries needing 3:1 (field borders, focus rings), `outlineVariant` for decorative dividers.
  • Dynamic color on Android 12+ with a static fallback.

2. Typography

  • All text from `MaterialTheme.typography` — no inline `fontSize`/`fontWeight`.
  • Correct scale: `display*` hero, `headline*` section headers, `title*` card/dialog titles, `body*` content, `label*` buttons/captions.

3. Shape

  • Corner radii from `MaterialTheme.shapes`, not hardcoded `RoundedCornerShape`.
  • Scale: `extraSmall` (4dp) chips, `small` (8dp) cards, `medium` (12dp) dialogs, `large` (16dp) sheets, `extraLarge` (28dp) FABs. Consistent shape language.

4. Elevation & surface

  • Elevation via **tonal color** (surface containers), not drop shadows; shadow elevation
Read more
Ships withandroid-skills

Android & KMP development skills for Claude Code, Codex, and Copilot CLI — architecture, Compose, coroutines, flows, networking, persistence, dependency injection, testing, debugging, and Gradle.

Get the whole plugin

Other skills on android-skills.