flutter-theming-apps
Customizes the visual appearance of a Flutter app using the theming system. Use when defining global styles, colors, or typography.
Файлы1
Открыть в GitHubSKILL.mdskills/flutter/theming/SKILL.md
GitHubFlutter Theming (Material 3)
Contents
- Core Theming Concepts
- Material 3 Guidelines
- Component Theme Normalization
- Button Styling
- Platform Idioms & Adaptive Design
- Workflows
- Examples
Core Theming Concepts
Flutter applies styling in a strict hierarchy: styles applied to the specific widget → themes that override the immediate parent theme → the main app theme.
- Define app-wide themes using the
themeproperty ofMaterialAppwith aThemeDatainstance. - Override themes for specific widget subtrees by wrapping them in a
Themewidget and usingTheme.of(context).copyWith(...). - Do not use deprecated
ThemeDataproperties:- Replace
accentColorwithcolorScheme.secondary. - Replace
accentTextThemewithtextTheme(usingcolorScheme.onSecondaryfor contrast). - Replace
AppBarTheme.colorwithAppBarTheme.backgroundColor.
- Replace
Material 3 Guidelines
Material 3 is the default theme as of Flutter 3.16.
- Colors: Generate color schemes using
ColorScheme.fromSeed(seedColor: Colors.blue). This ensures accessible contrast ratios. - Elevation: Material 3 uses
ColorScheme.surfaceTintto indicate elevation instead of just drop shadows. To revert to M2 shadow behavior, setsurfaceTint: Colors.transparentand define ashadowColor. - Typography: Material 3 updates font sizes, weights, and line heights. If text wrapping breaks legacy layouts, adjust
letterSpacingon the specificTextStyle. - Modern Components:
- Replace
BottomNavigationBarwithNavigationBar. - Replace
DrawerwithNavigationDrawer. - Replace
ToggleButtonswithSegmentedButton. - Use
FilledButtonfor a high-emphasis button without the elevation ofElevatedButton.
- Replace
Component Theme Normalization
When defining ThemeData, strictly use the *ThemeData suffix:
cardTheme: UseCardThemeData(NotCardTheme)dialogTheme: UseDialogThemeData(NotDialogTheme)tabBarTheme: UseTabBarThemeData(NotTabBarTheme)appBarTheme: UseAppBarThemeData(NotAppBarTheme)bottomAppBarTheme: UseBottomAppBarThemeData(NotBottomAppBarTheme)inputDecorationTheme: UseInputDecorationThemeData(NotInputDecorationTheme)
Button Styling
Legacy button classes (FlatButton, RaisedButton, OutlineButton) are obsolete.
- Use
TextButton,ElevatedButton, andOutlinedButton. - Configure button appearance using a
ButtonStyleobject. - For simple overrides, use
TextButton.styleFrom(foregroundColor: Colors.blue). - For state-dependent styling (hovered, focused, pressed, disabled), use
MaterialStateProperty.resolveWith.
Platform Idioms & Adaptive Design
When building adaptive apps, respect platform-specific norms.
- Scrollbars: Desktop users expect omnipresent scrollbars; mobile users expect them only during scrolling.
- Selectable Text: Web and desktop users expect text to be selectable. Use
SelectableText. - Horizontal Button Order: Windows places confirmation buttons on the left; macOS/Linux place them on the right.
- Context Menus & Tooltips: Desktop users expect hover and right-click interactions.
Workflows
Migrating Legacy Themes to Material 3
- Remove
useMaterial3: falsefromThemeData(it is true by default). - Replace manual
ColorSchemedefinitions withColorScheme.fromSeed(). - Search for and replace deprecated
accentColor,accentColorBrightness,accentIconTheme, andaccentTextTheme. - Search for
AppBarTheme(color: ...)and replace withbackgroundColor. - Update
ThemeDatacomponent properties to use*ThemeDataclasses. - Replace legacy buttons (
FlatButton→TextButton,RaisedButton→ElevatedButton,OutlineButton→OutlinedButton). - Replace legacy navigation components (
BottomNavigationBar→NavigationBar,Drawer→NavigationDrawer).
Implementing Adaptive UI Components
- If displaying a list/grid, wrap it in a
Scrollbarand setthumbVisibilitybased on platform. - If displaying read-only data, use
SelectableTextinstead ofText. - If implementing a dialog with action buttons, check the platform for button order.
- If implementing interactive elements, wrap them in
Tooltipwidgets for mouse hover.
Examples
Modern Material 3 ThemeData Setup
MaterialApp(
title: 'Adaptive App',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.light,
),
appBarTheme: const AppBarThemeData(
backgroundColor: Colors.deepPurple,
elevation: 0,
),
cardTheme: const CardThemeData(
elevation: 2,
),
textTheme: const TextTheme(
bodyMedium: TextStyle(letterSpacing: 0.2),
),
),
home: const MyHomePage(),
);
State-Dependent ButtonStyle
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
overlayColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return Colors.blue.withOpacity(0.04);
}
if (states.contains(MaterialState.focused) || states.contains(MaterialState.pressed)) {
return Colors.blue.withOpacity(0.12);
}
return null;
},
),
),
onPressed: () {},
child: const Text('Adaptive Button'),
)
Adaptive Dialog Button Order
Row(
textDirection: Platform.isWindows ? TextDirection.rtl : TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('Cancel'),
),
FilledButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('Confirm'),
),
],
)
Resources
- https://docs.flutter.dev/cookbook/design/themes
- https://docs.flutter.dev/ui/design
- https://docs.flutter.dev/ui/widgets/styling
- https://docs.flutter.dev/release/breaking-changes/material-3-migration
- https://docs.flutter.dev/release/breaking-changes/material-3-default
- https://docs.flutter.dev/release/breaking-changes/component-theme-normalization
- https://docs.flutter.dev/release/breaking-changes/component-theme-normalization-updates
- https://docs.flutter.dev/release/breaking-changes/buttons
- https://docs.flutter.dev/release/breaking-changes/theme-data-accent-properties
- https://docs.flutter.dev/release/breaking-changes/appbar-theme-color
- https://docs.flutter.dev/ui/adaptive-responsive/idioms