Flutter UX
This skill holds community tips, not Flutter team guidance: FlutterPro tips by Kamran Bekirov (FlutterPro), ApparenceKit tips and blog posts (ApparenceKit) and Kamran Bekirov's design-review skill (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. The official app guidance (architecture, routing, performance, versions) is 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; the Dart language is dart SKILL.md; framework-neutral durations and curves are 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 |
| 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 |
| 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 |
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 |
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 |
| Press feedback, stripping Material tap effects, haptics, snack bars, switch thumb icons, spinners and progress, the swipe-action hint | 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 |
| 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 |
| 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 |
| 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 |
Flutter web's web/index.html: boot progress, link preview cards and a tab title per page |
WEB-SHELL.md |
Dates with DateFormat, counts and money with NumberFormat, phone numbers while typing and on display, never showing "null" |
FORMATTING.md |
| Paged lists, next-page guards, pull-to-refresh, skeletons and loading-state decisions | 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 |
| 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 |
The rules
- Close the keyboard when the user is done:
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDragon scrollables with fields (chat screens staymanual), andFocusManager.instance.primaryFocus?.unfocus()before opening any modal, notFocusScope.of(context).unfocus()FlutterPro FlutterPro (KEYBOARD-AND-FOCUS.md). - Give every form a keyboard path:
textInputAction.nexton each single-line field,.done(or.send,.go,.search) on the last with the submit inonFieldSubmitted, andautofocus: trueon a page whose only control is one field FlutterPro FlutterPro (KEYBOARD-AND-FOCUS.md). - 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 FlutterPro (FORMS-AND-INPUT.md). - For image loading and first-frame assets, read flutter-ui IMAGES-AND-TYPOGRAPHY.md; image sizing is in Reserve image space. [FlutterPro, smooth-image-loading; reserve-image-space; precache-icons]
- Never show raw values: numbers through
NumberFormat, dates throughDateFormat, phone numbers formatted on display and while typing, and one shared guard that turnsnull,"null"and empty into "-" or "N/A" FlutterPro FlutterPro FlutterPro FlutterPro (FORMATTING.md). - Make the whole control take the tap and answer it:
HitTestBehavior.opaqueon aGestureDetectorwhose child has padding or gaps, and a subtle haptic on tab switches, successful submits, errors and toggles FlutterPro FlutterPro (MOTION-AND-FEEDBACK.md). - Where a tip disagrees with Flutter's docs, show both. The text-scale cap (limit it "to x1.1 at max", FlutterPro) against Flutter's "Make sure your layout has enough room to render all its contents when the font sizes are increased" (flutter ACCESSIBILITY.md); bottom padding instead of
SafeAreaon scrollables againstSafeAreaaround the body (flutter-ui LAYOUT-AND-RESPONSIVE.md); the full list is in REVIEW.md. - 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). Reviewing a pull request's diff is code-review SKILL.md; cleaning up agent-written code is anti-slop-code SKILL.md; a visual-design review ranked P0 to P3 is anti-slop-ui SKILL.md; its "Every data view has its states" also applies to image loading.
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 over the app, against 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 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.