# Flutter UX

> Polishes Flutter apps with community UX tips from FlutterPro (Kamran Bekirov) and ApparenceKit: forms, formatters and autofill, the keyboard and focus, sheets, tabs, route guards and shells, scrolling, press feedback and haptics, painting and media, permissions and notifications, device features, error views, version and changelog, Flutter web's HTML shell and formatting values, plus a find, pick and plan design review over 42 rules. Use when a Flutter screen works but feels rough, when polishing forms, sheets, lists or interaction feedback, or when auditing a Flutter app's UI and UX and writing fix plans.

- Skill: `quegenx/flutter-ux` (Agent Skill, multi-file: 16 files)
- Install (CLI): `npx get-skill add quegenx/flutter-ux`
- Raw SKILL.md: https://api.skillmd.com/api/skills/quegenx/flutter-ux/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: Quegenx (https://skillmd.com/u/quegenx)
- Updated: 2026-11-12
- Page: https://skillmd.com/skills/quegenx/flutter-ux

---


# Flutter UX

This skill holds community tips, not Flutter team guidance: FlutterPro tips by Kamran Bekirov ([FlutterPro](https://flutterpro.design)), ApparenceKit tips and blog posts ([ApparenceKit](https://apparencekit.dev)) and Kamran Bekirov's design-review skill ([improve-design](https://github.com/kamranbekirovyz/skills/tree/main/flutter-improve-design)). Most of it is the polish an app needs after it works: the keyboard closes when the user is done, lists leave room above the system bar, numbers and dates read the way the user's region writes them, and taps answer with motion and a haptic. Visual styling, typography, widget recipes, responsive layouts and animations are in [flutter-ui SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter-ui/SKILL.md). The official app guidance (architecture, routing, performance, versions) is [flutter SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter/SKILL.md), and it wins on correctness: where a tip differs from it, the topic file states both sides and tags each. Custom render objects are [flutter-render-objects SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter-render-objects/SKILL.md); the Dart language is [dart SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/dart/SKILL.md); framework-neutral durations and curves are [ui-animation SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/web-ui/ui-animation/SKILL.md).

Apply only the routes and checks for the selected job. Read a linked skill's named file from its installed folder when available, or from the linked source. Report an unavailable required reference instead of inventing it. [skill-authoring, DISTRIBUTION.md#composing-skills]

| The job | Read |
|---|---|
| Text fields and formatters that see paste and autofill (dial codes, amount limits), autofill and password managers, the clipboard, Save and Discard on edit forms, links inside translated sentences, checkbox lists, repeated taps | [FORMS-AND-INPUT.md](FORMS-AND-INPUT.md) |
| The keyboard action key, autofocus on single-field pages, dismissing the keyboard (on scroll, on a tap outside, before a modal), watching its visibility, a centered form above it, forms in bottom sheets, shortcuts | [KEYBOARD-AND-FOCUS.md](KEYBOARD-AND-FOCUS.md) |
| Sheets as routes (spring sheet, scroll-to-dismiss, the iOS 26 sheet, popups that fit their content), dialog and sheet results, the Android back flag, tab reselect, keeping scroll position, page transitions per platform, adaptive date pickers | [NAVIGATION-AND-SHEETS.md](NAVIGATION-AND-SHEETS.md) |
| Nested navigators and `rootNavigator`, a sidebar on a go_router `StatefulShellRoute`, route guards (`redirect`, rebuilding the router from Riverpod, guard widgets) | [ROUTE-GUARDS-AND-SHELLS.md](ROUTE-GUARDS-AND-SHELLS.md) |
| Bottom padding instead of `SafeArea` on scroll views, edge-to-edge horizontal lists, status-bar tap to top, scrollbars, keeping the selected tab in view, `ShaderMask` edge fades, the text-scale cap, `GestureDetector` hit areas | [SCROLLING-AND-LAYOUT.md](SCROLLING-AND-LAYOUT.md) |
| Press feedback, stripping Material tap effects, haptics, snack bars, switch thumb icons, spinners and progress, the swipe-action hint | [MOTION-AND-FEEDBACK.md](MOTION-AND-FEEDBACK.md) |
| `CustomPainter` (redraw from a model, round progress, hit testing, `save`/`restore`, text and images on a canvas), a painter or widget to an image, `share_plus`, native cache-file sharing instead of downloading, `package:image`, cropping, sounds, fullscreen video | [PAINTING-AND-MEDIA.md](PAINTING-AND-MEDIA.md) |
| Runtime permissions and the denied path, photos with no permission, priming the notification prompt, FCM delivery handoff, iOS time-sensitive notifications, rescheduling on a timezone or clock change | [NOTIFICATIONS-AND-PERMISSIONS.md](NOTIFICATIONS-AND-PERMISSIONS.md) |
| Status bar style, blocking screenshots, the device's IANA timezone, showing the app version, iOS home-screen widgets, a portrait lock, platform detection, wakelock and social app links | [DEVICE-FEATURES.md](DEVICE-FEATURES.md) |
| A friendly error view, breaking on handled exceptions in debug, the version line, a changelog after each update, forced and soft update and maintenance mode, real screen names in analytics, a debug-only admin panel, app lifecycle observers and post-frame work | [APP-LIFECYCLE.md](APP-LIFECYCLE.md) |
| Flutter web's `web/index.html`: boot progress, link preview cards and a tab title per page | [WEB-SHELL.md](WEB-SHELL.md) |
| Dates with `DateFormat`, counts and money with `NumberFormat`, phone numbers while typing and on display, never showing "null" | [FORMATTING.md](FORMATTING.md) |
| Paged lists, next-page guards, pull-to-refresh, skeletons and loading-state decisions | [PAGINATION-AND-LOADING.md](PAGINATION-AND-LOADING.md) |
| A whole-app design review: hard rules, find, pick, then plan, the self-contained plan template, and where catalog rules differ from Flutter's docs | [REVIEW.md](REVIEW.md) |
| The 42 review rules, each with what to flag, where to hunt, the fix in one line and the topic file that holds it | [REVIEW-CATALOG.md](REVIEW-CATALOG.md) |

## The rules

1. **Close the keyboard when the user is done:** `keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag` on scrollables with fields (chat screens stay `manual`), and `FocusManager.instance.primaryFocus?.unfocus()` before opening any modal, not `FocusScope.of(context).unfocus()` [FlutterPro](https://flutterpro.design/details/dismiss-keyboard-on-scroll) [FlutterPro](https://flutterpro.design/details/unfocus-before-modal) ([KEYBOARD-AND-FOCUS.md](KEYBOARD-AND-FOCUS.md)).
2. **Give every form a keyboard path:** `textInputAction` `.next` on each single-line field, `.done` (or `.send`, `.go`, `.search`) on the last with the submit in `onFieldSubmitted`, and `autofocus: true` on a page whose only control is one field [FlutterPro](https://flutterpro.design/details/text-input-action) [FlutterPro](https://flutterpro.design/details/autofocus-single-field) ([KEYBOARD-AND-FOCUS.md](KEYBOARD-AND-FOCUS.md)).
3. **Catch paste and autofill in `inputFormatters`:** every edit, typed or pasted, goes through them, so strip a doubled dial code there and block an amount past its limit there instead of erroring afterwards [FlutterPro](https://flutterpro.design/details/autofill-dial-code) [FlutterPro](https://flutterpro.design/details/max-amount-formatter) ([FORMS-AND-INPUT.md](FORMS-AND-INPUT.md)).
4. **For image loading and first-frame assets,** read [flutter-ui IMAGES-AND-TYPOGRAPHY.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter-ui/IMAGES-AND-TYPOGRAPHY.md); image sizing is in [Reserve image space](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter-ui/IMAGES-AND-TYPOGRAPHY.md#reserve-image-space). [FlutterPro, smooth-image-loading; reserve-image-space; precache-icons]
5. **Never show raw values:** numbers through `NumberFormat`, dates through `DateFormat`, phone numbers formatted on display and while typing, and one shared guard that turns `null`, `"null"` and empty into "-" or "N/A" [FlutterPro](https://flutterpro.design/details/format-numbers-for-humans) [FlutterPro](https://flutterpro.design/details/format-date-times) [FlutterPro](https://flutterpro.design/details/format-phone-numbers) [FlutterPro](https://flutterpro.design/details/never-show-null) ([FORMATTING.md](FORMATTING.md)).
6. **Make the whole control take the tap and answer it:** `HitTestBehavior.opaque` on a `GestureDetector` whose child has padding or gaps, and a subtle haptic on tab switches, successful submits, errors and toggles [FlutterPro](https://flutterpro.design/details/gesture-detector-hit-area) [FlutterPro](https://flutterpro.design/details/haptic-feedback) ([MOTION-AND-FEEDBACK.md](MOTION-AND-FEEDBACK.md)).
7. **Where a tip disagrees with Flutter's docs, show both.** The text-scale cap (limit it "to x1.1 at max", [FlutterPro](https://flutterpro.design/details/text-scale-factor)) against Flutter's "Make sure your layout has enough room to render all its contents when the font sizes are increased" ([flutter ACCESSIBILITY.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter/ACCESSIBILITY.md#design-values)); bottom padding instead of `SafeArea` on scrollables against `SafeArea` around the body ([flutter-ui LAYOUT-AND-RESPONSIVE.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter-ui/LAYOUT-AND-RESPONSIVE.md#safearea-and-mediaquery)); the full list is in [REVIEW.md](REVIEW.md#where-a-rule-differs-from-flutters-docs).
8. **A design review never edits the app.** It writes only under `docs/improvements/design/`, prints findings without locations or counts, waits for the developer to pick, and writes plans a session with zero context can execute [improve-design] ([REVIEW.md](REVIEW.md)). Reviewing a pull request's diff is [code-review SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/engineering/code-review/SKILL.md); cleaning up agent-written code is [anti-slop-code SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/anti-ai-slop/anti-slop-code/SKILL.md); a visual-design review ranked P0 to P3 is [anti-slop-ui SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/anti-ai-slop/anti-slop-ui/SKILL.md); its "Every data view has its states" also applies to [image loading](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter-ui/IMAGES-AND-TYPOGRAPHY.md).

## Prove it

For a focused form, sheet, scrolling, feedback or formatting task, verify the touched behavior with its topic file's checks. The whole-app review and the broader device walk below apply when that scope was selected; they are not prerequisites for every local polish change. [FlutterPro; ApparenceKit; improve-design, REVIEW.md]

For a whole-app design review, a run of [REVIEW.md](REVIEW.md) over the app, against [REVIEW-CATALOG.md](REVIEW-CATALOG.md), returns no finding for the rules the team chose to adopt; on a device, scrolling a form closes the keyboard, the last field's action key submits, a modal closes without the keyboard coming back, the last list item clears the system bar, every number, date and phone number reads in the user's format; each rule that differs from [flutter SKILL.md](https://github.com/Quegenx/agent-skills/blob/main/skills/mobile/flutter/SKILL.md) was decided with both sides shown, and the app still passes that skill's checks at the largest OS font; and every file's own Prove it checks pass for the parts you touched.

