1. Performance & Rendering
- Const-First: Every widget that can be
constMUST beconst. - Lazy Rendering: Use
SliverList.builderorSliverGrid.builderfor lists > 10 items. - Repaint Boundaries: Wrap complex animations in
RepaintBoundary. - Impeller Rendering: Impeller is the default rendering engine for iOS and Android. Ensure custom canvas paints are optimized and do not rely on Skia-specific behaviors.
- Isolate Parsing: Use
compute()orIsolatefor JSON > 1MB. - BuildContext Safety: Check
mountedbefore usingcontextacross async gaps.
2. Design Tokens (Theming)
Use AppColors, AppSpacing, AppRadius, and AppTypography. NEVER hardcode raw values.
- Colors: Use
context.colorScheme.primaryorAppColors. Support light/dark modes. - Spacing: Use
AppSpacing.sm(8),AppSpacing.md(16), etc. UseSizedBoxfor gaps. - Radius: Use
AppRadius.md(12) for consistent rounding. - Typography: Use
context.textTheme.bodyMedium. Support text scaling.
3. Reusable Components
- Single Responsibility: Each component has one clear purpose.
- Parameterization: Expose parameters for customization.
- Complexity: Extract widgets or code blocks used multiple times into
core/views/widgets. - Keys: Assign
Key('feature_action_id')to interactive widgets for test access.
4. Widget & Interaction Patterns
- Extraction: STRICTLY prohibit private
_build*()methods. Extract into separate widget classes. - Slivers: Prefer
CustomScrollViewwith Slivers for non-trivial scrollable layouts. - FAB: Use Floating Action Buttons for primary positive actions (Add, Create).
- Scroll Padding: Add dynamic bottom padding when a FAB or BottomBar is present to prevent overlap.
- Pop Handling: NEVER use the deprecated
WillPopScopewidget. Use the standardPopScopewidget to intercept or block back-navigation. - Sheets vs Screens: Prefer full
Scaffoldscreens overModalBottomSheetfor complex forms.
5. Adaptive & Responsive Design and Common Fixes
- Mobile First: Design for mobile, then adapt for tablet (
600-840dp) and desktop (>840dp). UseMediaQuery.sizeOf(context).width. - Layout Builder: Use
LayoutBuilderwhen widget rendering depends on the immediate parent's constraints, not the whole screen. - Safe Area & Android 15: Wrap main layouts in
SafeAreato avoid device notches and system bar overlays. Since Android 15 enforces edge-to-edge rendering by default, useMediaQuery.paddingOf(context)orSafeAreato prevent widgets from clipping under the system status or navigation bars. - Modular UI Imports: Flutter 3.44+ decouples
materialandcupertinofrom the core framework. In pure structural widgets, import onlypackage:flutter/widgets.dartto maintain clear library separation. - Overflow Fixes:
A RenderFlex overflowed...: Typically means a widget is demanding more space than available in aRoworColumn. Wrap the offending widget inExpandedorFlexible.Vertical viewport was given unbounded height: Often happens when nesting scrollable views (likeListViewinsideColumn). UseExpandedon theListViewor setshrinkWrap: true.
- Rules: Never lock orientation unless strictly required by a unique feature. Support keyboard navigation and hover effects for desktop users.
6. Responsive Layout Patterns
LayoutBuilder vs MediaQuery
| Tool | Use When | Returns |
|---|---|---|
| MediaQuery.sizeOf(context) | Layout depends on screen size (app-level breakpoints) | Size of the screen |
| LayoutBuilder | Layout depends on parent constraints (widget-level) | BoxConstraints from parent |
Rule: Use MediaQuery for page-level layouts. Use LayoutBuilder for reusable components that adapt to their container.
Breakpoint Conventions
| Window Class | Width | Layout | Columns | |---|---|---|---| | Compact | < 600dp | Single column, bottom nav | 4 | | Medium | 600–840dp | Two-pane, navigation rail | 8 | | Expanded | > 840dp | Multi-pane, side navigation | 12 |
Adaptive Layout Pattern
Widget build(BuildContext context) {
final width = MediaQuery.sizeOf(context).width;
return switch (width) {
< 600 => const MobileLayout(),
< 840 => const TabletLayout(),
_ => const DesktopLayout(),
};
}
Constraint Widgets
| Widget | Behavior | Use When |
|---|---|---|
| Expanded | Fill ALL remaining space in Row/Column | Child should stretch |
| Flexible | Allow child to be SMALLER than remaining space | Child has natural size |
| FractionallySizedBox | Size as fraction of parent (e.g., 0.5 = 50%) | Proportional layouts |
| ConstrainedBox | Set min/max constraints | Bounded flexibility |
| SizedBox | Fixed absolute dimensions | Known exact size |
7. UI States & Accessibility
- States: Always handle Loading, Error, and Empty states with clear messaging.
- Accessibility: Include
Semanticslabels. Ensure 48x48 dp touch targets. WCAG AA contrast.
Scan to join WeChat group