### Snackbar Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/snackbars.md An example demonstrating the usage of a SnackBar with an action button, including its content and action properties. ```dart SnackBar( behavior: SnackBarBehavior.floating, content: Text('Text label'), action: SnackBarAction( label: 'Action', onPressed: () {}, ), ) ``` -------------------------------- ### Flutter SnackBar Theming Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/snackbars.md This example demonstrates a Flutter `SnackBar` with an action button, styled using the Material.io Shrine color theme. It includes setup for `MaterialApp`, `Scaffold`, and custom `ThemeData` with color schemes and text themes. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, home: SnackBarsDemo(), theme: buildShrineTheme(), ); } } class SnackBarsDemo extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Snackbars'), actions: [SnackbarButton()], ), body: Container( decoration: BoxDecoration( image: DecorationImage( image: NetworkImage( 'replace with url for snackbars-background.jpg after merge'), fit: BoxFit.cover, ), ), ), ); } } class SnackbarButton extends StatelessWidget { Widget build(BuildContext context) { return RaisedButton( onPressed: () { final snackBar = SnackBar( behavior: SnackBarBehavior.floating, content: Text('Text label'), action: SnackBarAction( label: 'Action', onPressed: () {}, ), ); // Find the Scaffold in the widget tree and use // it to show a SnackBar. Scaffold.of(context).showSnackBar(snackBar); }, child: Text('Show SnackBar'), ); } } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, accentColor: shrineBrown900, primaryColor: shrinePink100, buttonColor: shrinePink100, scaffoldBackgroundColor: shrineBackgroundWhite, cardColor: shrineBackgroundWhite, textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100), errorColor: shrineErrorRed, buttonTheme: const ButtonThemeData( colorScheme: _shrineColorScheme, textTheme: ButtonTextTheme.normal, ), primaryIconTheme: _customIconTheme(base.iconTheme), textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), iconTheme: _customIconTheme(base.iconTheme), ); } IconThemeData _customIconTheme(IconThemeData original) { return original.copyWith(color: shrineBrown900); } TextTheme _buildShrineTextTheme(TextTheme base) { return base .copyWith( caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14, letterSpacing: defaultLetterSpacing, ), button: base.button.copyWith( fontWeight: FontWeight.w500, fontSize: 14, letterSpacing: defaultLetterSpacing, ), ) .apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrinePink50, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); const Color shrinePink50 = Color(0xFFFEEAE6); const Color shrinePink100 = Color(0xFFFEDBD0); const Color shrinePink300 = Color(0xFFFBB8AC); const Color shrinePink400 = Color(0xFFEAA4A4); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineBrown600 = Color(0xFF7D4F52); const Color shrineErrorRed = Color(0xFFC5032B); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Colors.white; const double defaultLetterSpacing = 0.03; ``` -------------------------------- ### Flutter DropdownButton Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/menus.md Illustrates the implementation of an exposed dropdown menu using Flutter's DropdownButton widget. This example shows how to manage the selected value and define the list of available options. ```dart DropdownButton( value: dropdownValue, items: [ DropdownMenuItem( value: 'Option 1', child: Text('Option 1'), ), DropdownMenuItem( value: 'Option 2', child: Text('Option 2'), ), DropdownMenuItem( value: 'Option 3', child: Text('Option 3'), ), DropdownMenuItem( value: 'Option 4', child: Text('Option 4'), ), DropdownMenuItem( value: 'Option 5', child: Text('Option 5'), ), DropdownMenuItem( value: 'Option 6', child: Text('Option 6'), ), ], onChanged: (value) { setState(() { dropdownValue = value; }); }, ) ``` -------------------------------- ### Flutter Modal Navigation Drawer Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/nav_drawer.md This example demonstrates the implementation of a modal navigation drawer in a Flutter application. It utilizes the `Drawer` widget from the `material` package and `ListView` for structuring the drawer content. The example shows how to handle item selection and display a basic app layout. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final appTitle = 'Drawer Demo'; @override Widget build(BuildContext context) { return MaterialApp( title: appTitle, home: MyHomePage(title: appTitle), theme: ThemeData( primaryColor: Color(0xFF6200EE), ), ); } } class MyHomePage extends StatefulWidget { final String title; MyHomePage({Key key, this.title}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _selectedDestination = 0; @override Widget build(BuildContext context) { final theme = Theme.of(context); final textTheme = theme.textTheme; return Scaffold( appBar: AppBar( title: Text(widget.title), ), drawer: Drawer( child: ListView( // Important: Remove any padding from the ListView. padding: EdgeInsets.zero, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Header', style: textTheme.headline6, ), ), Divider( height: 1, thickness: 1, ), ListTile( leading: Icon(Icons.favorite), title: Text('Item 1'), selected: _selectedDestination == 0, onTap: () => selectDestination(0), ), ListTile( leading: Icon(Icons.delete), title: Text('Item 2'), selected: _selectedDestination == 1, onTap: () => selectDestination(1), ), ListTile( leading: Icon(Icons.label), title: Text('Item 3'), selected: _selectedDestination == 2, onTap: () => selectDestination(2), ), Divider( height: 1, thickness: 1, ), Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Label', ), ), ListTile( leading: Icon(Icons.bookmark), title: Text('Item A'), selected: _selectedDestination == 3, onTap: () => selectDestination(3), ), ], ), ), body: GridView.count( crossAxisCount: 2, crossAxisSpacing: 20, mainAxisSpacing: 20, padding: EdgeInsets.all(20), childAspectRatio: 3 / 2, children: [ Image.asset('assets/nav-drawer-1.jpg'), Image.asset('assets/nav-drawer-2.jpg'), Image.asset('assets/nav-drawer-3.jpg'), Image.asset('assets/nav-drawer-4.jpg'), ], ), ); } void selectDestination(int index) { setState(() { _selectedDestination = index; }); } } ``` -------------------------------- ### Flutter InputChip Theming Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/chips.md Demonstrates how to theme Flutter InputChips using a custom ThemeData. This example applies a 'Shrine' theme, customizing colors, icon themes, and text themes to alter the appearance of InputChip widgets. ```dart import "package:flutter/material.dart"; void main() { runApp(App()); } class App extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Checkboxes Demo', debugShowCheckedModeBanner: false, theme: _buildShrineTheme(), home: Scaffold( appBar: AppBar( title: Text('Input Theme Chips Demo'), ), body: Center( child: Column( children: [ InputChip( avatar: Icon(Icons.add_shopping_cart), label: Text('Input 1'), onSelected: (bool value) {}, ), InputChip( avatar: Icon(Icons.card_giftcard), label: Text('Input 2'), onSelected: (bool value) {}, ), InputChip( avatar: Icon(Icons.credit_card), label: Text('Input 3'), onSelected: (bool value) {}, ), ], ), ), ), ); } } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, toggleableActiveColor: shrinePink400, accentColor: shrineBrown900, primaryColor: shrinePink100, buttonColor: shrinePink100, scaffoldBackgroundColor: shrineBackgroundWhite, cardColor: shrineBackgroundWhite, textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100), errorColor: shrineErrorRed, primaryIconTheme: _customIconTheme(base.iconTheme), textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), iconTheme: _customIconTheme(base.iconTheme), ); } IconThemeData _customIconTheme(IconThemeData original) { return original.copyWith(color: shrineBrown900); } TextTheme _buildShrineTextTheme(TextTheme base) { return base.apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrinePink50, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); const Color shrinePink50 = Color(0xFFFEEAE6); const Color shrinePink100 = Color(0xFFFEDBD0); const Color shrinePink300 = Color(0xFFFBB8AC); const Color shrinePink400 = Color(0xFFEAA4A4); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineBrown600 = Color(0xFF7D4F52); const Color shrineErrorRed = Color(0xFFC5032B); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Colors.white; ``` -------------------------------- ### Flutter InputChip Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/chips.md Demonstrates how to use the InputChip widget in Flutter. InputChips represent complex information in a compact form, allowing user input and verification. This example shows creating multiple input chips with icons and labels. ```Dart import 'package:flutter/material.dart'; void main() { runApp(InputChipsDemo()); } class InputChipsDemo extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Input Chips Demo', debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: Text('Input Chips Demo'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ InputChip( avatar: Icon(Icons.person_outline), label: Text('Input 1'), onSelected: (bool value) { print('InputChip 1 selected: $value'); }, ), SizedBox(height: 10), InputChip( avatar: Icon(Icons.email_outlined), label: Text('Input 2'), onSelected: (bool value) { print('InputChip 2 selected: $value'); }, ), SizedBox(height: 10), InputChip( avatar: Icon(Icons.settings_outlined), label: Text('Input 3'), onSelected: (bool value) { print('InputChip 3 selected: $value'); }, ), ], ), ), ), ); } } ``` -------------------------------- ### Flutter Backdrop Implementation Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/backdrop.md This snippet refers to an example implementation of a simple backdrop component in Flutter. It utilizes existing widgets like PositionedTransition in conjunction with AnimationController to achieve the desired open/close motion. The example is located in the MDC-Flutter codelabs repository. ```flutter /* * Code example for building a simple backdrop can be found in the * MDC-Flutter codelabs repo: * https://github.com/material-components/material-components-flutter-codelabs/blob/104-complete/mdc_100_series/lib/backdrop.dart * * This example uses existing widgets such as PositionedTransition in tandem with the AnimationController. * It also uses some custom widgets to establish the desired look. */ // No direct code provided in the source text, only a reference to an external file. ``` -------------------------------- ### Flutter Action Chip Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/chips.md This Flutter code demonstrates how to use `ActionChip` widgets, which are designed to trigger actions related to primary content. The example shows chips with icons and labels, and how to define an `onPressed` callback for each action. ```dart @override Widget build(BuildContext context) { return MaterialApp( title: 'Action Chip Demo', debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: Text('Action Chips Demo'), ), body: Center( child: Column( children: [ ActionChip( avatar: Icon(Icons.favorite), label: Text('Action 1'), onPressed: () {}, ), ActionChip( avatar: Icon(Icons.delete), label: Text('Action 2'), onPressed: () {}, ), ActionChip( avatar: Icon(Icons.alarm), label: Text('Action 3'), onPressed: () {}, ), ActionChip( avatar: Icon(Icons.location_on), label: Text('Action 4'), onPressed: () {}, ), ], ), ), ), ); } ``` -------------------------------- ### Flutter Top App Bar Theming Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/top_app_bars.md Demonstrates applying Material Theming to a Flutter Top App Bar. This example customizes the `AppBar` with a specific color scheme, icon theme, and text theme, creating a distinct visual style for the application. It includes the necessary `MaterialApp`, `Scaffold`, and theme data definitions. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: MyHomePage(), theme: _buildShrineTheme(), ); } } class MyHomePage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: Icon(Icons.menu), title: Text('Page title'), actions: [ Icon(Icons.favorite), Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: Icon(Icons.search), ), Icon(Icons.more_vert), ], ), body: Container(), ); } } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, accentColor: shrineBrown900, primaryColor: shrinePink100, buttonColor: shrinePink100, scaffoldBackgroundColor: shrineBackgroundWhite, cardColor: shrineBackgroundWhite, textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100), errorColor: shrineErrorRed, buttonTheme: const ButtonThemeData( colorScheme: _shrineColorScheme, textTheme: ButtonTextTheme.normal, ), primaryIconTheme: _customIconTheme(base.iconTheme), textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), iconTheme: _customIconTheme(base.iconTheme), ); } IconThemeData _customIconTheme(IconThemeData original) { return original.copyWith(color: shrineBrown900); } TextTheme _buildShrineTextTheme(TextTheme base) { return base .copyWith( caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14, letterSpacing: defaultLetterSpacing, ), button: base.button.copyWith( fontWeight: FontWeight.w500, fontSize: 14, letterSpacing: defaultLetterSpacing, ), ) .apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrinePink50, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); const Color shrinePink50 = Color(0xFFFEEAE6); const Color shrinePink100 = Color(0xFFFEDBD0); const Color shrinePink300 = Color(0xFFFBB8AC); const Color shrinePink400 = Color(0xFFEAA4A4); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineBrown600 = Color(0xFF7D4F52); const Color shrineErrorRed = Color(0xFFC5032B); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Colors.white; const defaultLetterSpacing = 0.03; ``` -------------------------------- ### Alert dialog example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/dialogs.md Demonstrates how to create an AlertDialog in Flutter, which is used to interrupt users with urgent information or require a decision. It requires the `package:flutter/material.dart` library and a `MaterialApp` widget. The example shows how to define the title, content, and action buttons for the dialog. ```dart AlertDialog( title: Text('Reset settings?'), content: Text('This will reset your device to its default factory settings.'), actions: [ FlatButton( textColor: Color(0xFF6200EE), onPressed: () {}, child: Text('CANCEL'), ), FlatButton( textColor: Color(0xFF6200EE), onPressed: () {}, child: Text('ACCEPT'), ), ], ) ``` -------------------------------- ### Flutter Material Card Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/cards.md Demonstrates how to create a Material Design Card in Flutter with various elements like ListTile, Text, ButtonBar, and Images. This example showcases a common pattern for displaying content within a card. ```dart Card( clipBehavior: Clip.antiAlias, child: Column( children: [ ListTile( leading: Icon(Icons.arrow_drop_down_circle), title: const Text('Card title 1'), subtitle: Text( 'Secondary Text', style: TextStyle(color: Colors.black.withOpacity(0.6))), ), Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Greyhound divisively hello coldly wonderfully marginally far upon excluding.', style: TextStyle(color: Colors.black.withOpacity(0.6))), ), ButtonBar( alignment: MainAxisAlignment.start, children: [ FlatButton( textColor: const Color(0xFF6200EE), onPressed: () { // Perform some action }, child: const Text('ACTION 1'), ), FlatButton( textColor: const Color(0xFF6200EE), onPressed: () { // Perform some action }, child: const Text('ACTION 2'), ), ], ), Image.asset('assets/card-sample-image.jpg'), Image.asset('assets/card-sample-image-2.jpg'), ], ), ) ``` -------------------------------- ### Dialog Theming Example with Shrine Theme Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/dialogs.md This Flutter code snippet showcases how to apply custom theming to an AlertDialog using the Shrine theme. It includes the necessary imports, widget structure, and theme data definitions for a complete, runnable example. The dialog features custom styling for its content and actions. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, home: MyHomePage(), theme: _buildShrineTheme(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { final AlertDialog dialog = AlertDialog( title: Text('Title'), contentPadding: EdgeInsets.zero, content: Column( mainAxisSize: MainAxisSize.min, children: [ for (int i = 1; i <= 3; i++) ListTile( title: Text( 'option $i', style: Theme.of(context) .textTheme .subtitle1 .copyWith(color: shrineBrown900), ), leading: Radio( value: i, groupValue: 1, onChanged: (_) {}, ), ), ], ), actions: [ FlatButton( textColor: shrineBrown900, onPressed: () => Navigator.pop(context), child: Text('ACTION 1'), ), FlatButton( textColor: shrineBrown900, onPressed: () => Navigator.pop(context), child: Text('ACTION 2'), ), ], ); return Scaffold( body: Center( child: FlatButton( onPressed: () { showDialog(context: context, builder: (context) => dialog); }, child: Text("SHOW DIALOG"), ), ), ); } } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, toggleableActiveColor: shrinePink400, accentColor: shrineBrown900, primaryColor: shrinePink100, buttonColor: shrinePink100, scaffoldBackgroundColor: shrineBackgroundWhite, cardColor: shrineBackgroundWhite, textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100), errorColor: shrineErrorRed, buttonTheme: const ButtonThemeData( colorScheme: _shrineColorScheme, textTheme: ButtonTextTheme.normal, ), primaryIconTheme: _customIconTheme(base.iconTheme), textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), iconTheme: _customIconTheme(base.iconTheme), dialogTheme: DialogTheme( backgroundColor: shrinePink100, ), ); } IconThemeData _customIconTheme(IconThemeData original) { return original.copyWith(color: shrineBrown900); } TextTheme _buildShrineTextTheme(TextTheme base) { return base .copyWith( caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14, letterSpacing: defaultLetterSpacing, ), button: base.button.copyWith( fontWeight: FontWeight.w500, fontSize: 14, letterSpacing: defaultLetterSpacing, ), ) .apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrineBrown900, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); const Color shrinePink50 = Color(0xFFFEEAE6); const Color shrinePink100 = Color(0xFFFEDBD0); const Color shrinePink300 = Color(0xFFFBB8AC); const Color shrinePink400 = Color(0xFFEAA4A4); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineBrown600 = Color(0xFF7D4F52); const Color shrineErrorRed = Color(0xFFC5032B); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Colors.white; const double defaultLetterSpacing = 0.03; ``` -------------------------------- ### Standard Navigation Drawer Example in Flutter Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/nav_drawer.md This example demonstrates how to build a standard navigation drawer in Flutter. It simulates a standard drawer using a `Row` containing a `Drawer` widget and a `Scaffold`. The `Drawer` widget itself is populated with `ListTile` widgets for navigation items. ```dart class MyHomePage extends StatefulWidget { final String title; MyHomePage({Key key, this.title}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _selectedDestination = 0; @override Widget build(BuildContext context) { final theme = Theme.of(context); final textTheme = theme.textTheme; return Row( children: [ Drawer( child: ListView( // Important: Remove any padding from the ListView. padding: EdgeInsets.zero, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Header', style: textTheme.headline6, ), ), Divider( height: 1, thickness: 1, ), ListTile( leading: Icon(Icons.favorite), title: Text('Item 1'), selected: _selectedDestination == 0, onTap: () => selectDestination(0), ), ListTile( leading: Icon(Icons.delete), title: Text('Item 2'), selected: _selectedDestination == 1, onTap: () => selectDestination(1), ), ListTile( leading: Icon(Icons.label), title: Text('Item 3'), selected: _selectedDestination == 2, onTap: () => selectDestination(2), ), Divider( height: 1, thickness: 1, ), Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Label', ), ), ListTile( leading: Icon(Icons.bookmark), title: Text('Item A'), selected: _selectedDestination == 3, onTap: () => selectDestination(3), ), ], ), ), VerticalDivider( width: 1, thickness: 1, ), Expanded( child: Scaffold( appBar: AppBar( title: Text(widget.title), ), body: GridView.count( crossAxisCount: 2, crossAxisSpacing: 20, mainAxisSpacing: 20, padding: EdgeInsets.all(20), childAspectRatio: 3 / 2, children: [ Image.asset('assets/nav-drawer-1.jpg'), Image.asset('assets/nav-drawer-2.jpg'), Image.asset('assets/nav-drawer-3.jpg'), Image.asset('assets/nav-drawer-4.jpg'), ], ), ), ), ], ); } void selectDestination(int index) { setState(() { _selectedDestination = index; }); } } ``` -------------------------------- ### Flutter Theming Example with Shrine Theme Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/bottom_app_bars.md This example demonstrates how to apply a custom Material Design theme, the Shrine theme, to a Flutter application. It showcases a BottomAppBar with specific color schemes and typography defined by the Shrine theme, illustrating the flexibility of Flutter's theming system. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: MyHomePage(), theme: _buildShrineTheme(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: BottomAppBar( child: Row( children: [ IconButton(icon: Icon(Icons.menu), onPressed: () {}), Spacer(), IconButton(icon: Icon(Icons.search), onPressed: () {}), IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), ], ), ), floatingActionButton: FloatingActionButton(child: Icon(Icons.add), onPressed: () {}), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, ); } } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, textTheme: _buildShrineTextTheme(base.textTheme), ); } TextTheme _buildShrineTextTheme(TextTheme base) { return base .copyWith( caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14, letterSpacing: defaultLetterSpacing, ), button: base.button.copyWith( fontWeight: FontWeight.w500, fontSize: 14, letterSpacing: defaultLetterSpacing, ), ) .apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrinePink50, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); const Color shrinePink50 = Color(0xFFFEEAE6); const Color shrinePink100 = Color(0xFFFEDBD0); const Color shrinePink300 = Color(0xFFFBB8AC); const Color shrinePink400 = Color(0xFFEAA4A4); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineBrown600 = Color(0xFF7D4F52); const Color shrineErrorRed = Color(0xFFC5032B); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Colors.white; const defaultLetterSpacing = 0.03; ``` -------------------------------- ### Flutter Tooltip Theming Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/tooltips.md Illustrates how to theme Flutter `Tooltip` widgets using `TooltipThemeData`. This example customizes the tooltip's background color, shape (using `StadiumBorder`), and text style, applying a Material-like theme. It shows how to override default tooltip appearance for a consistent UI. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Tooltip Demo', debugShowCheckedModeBanner: false, theme: ThemeData( tooltipTheme: TooltipThemeData( decoration: ShapeDecoration( color: Color(0xFF232F34), shape: StadiumBorder(), ), textStyle: TextStyle(color: Colors.white), ), ), home: Scaffold( body: Center( child: Tooltip( message: 'Play', child: Icon(Icons.play_arrow), ), ), ), ); } } ``` -------------------------------- ### Flutter Material Switch Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/switches.md Demonstrates using the Material Design Switch widget in Flutter within a list. This example shows how to manage the state of multiple switches, including handling disabled states and applying custom active colors. ```dart Column( children: [ for (int i = 0; i <= count; i++) ListTile( title: Text( 'Switch ${i + 1}', style: Theme.of(context).textTheme.subtitle1.copyWith( color: i == count ? Colors.black38 : Colors.black), ), leading: Switch( value: _values[i], activeColor: Color(0xFF6200EE), onChanged: i == count ? null : (bool value) { setState(() { _values[i] = value; }); }, ), ), ], ) ``` -------------------------------- ### Flutter Data Table Theming Example Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/data_tables.md Demonstrates applying custom themes, specifically the Shrine theme, to Flutter's `PaginatedDataTable`. This example includes the main application structure, the `DataTableDemo` widget, the `_DataSource` class for populating the table, and the `_buildShrineTheme` function with its helpers to define the custom theme. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: _buildShrineTheme(), home: DataTableDemo(), ); } } class DataTableDemo extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Data Tables'), ), body: ListView( padding: const EdgeInsets.all(16), children: [ PaginatedDataTable( header: Text('Header Text'), rowsPerPage: 4, columns: [ DataColumn(label: Text('Header A')), DataColumn(label: Text('Header B')), DataColumn(label: Text('Header C')), DataColumn(label: Text('Header D')), ], source: _DataSource(context), ), ], ), ); } } class _Row { _Row( this.valueA, this.valueB, this.valueC, this.valueD, ); final String valueA; final String valueB; final String valueC; final int valueD; bool selected = false; } class _DataSource extends DataTableSource { _DataSource(this.context) { _rows = <_Row>[ _Row('Cell A1', 'CellB1', 'CellC1', 1), _Row('Cell A2', 'CellB2', 'CellC2', 2), _Row('Cell A3', 'CellB3', 'CellC3', 3), _Row('Cell A4', 'CellB4', 'CellC4', 4), ]; } final BuildContext context; List<_Row> _rows; int _selectedCount = 0; @override DataRow getRow(int index) { assert(index >= 0); if (index >= _rows.length) return null; final row = _rows[index]; return DataRow.byIndex( index: index, selected: row.selected, onSelectChanged: (value) { if (row.selected != value) { _selectedCount += value ? 1 : -1; assert(_selectedCount >= 0); row.selected = value; notifyListeners(); } }, cells: [ DataCell(Text(row.valueA)), DataCell(Text(row.valueB)), DataCell(Text(row.valueC)), DataCell(Text(row.valueD.toString())), ], ); } @override int get rowCount => _rows.length; @override bool get isRowCountApproximate => false; @override int get selectedRowCount => _selectedCount; } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, accentColor: shrineBrown900, primaryColor: shrinePink100, buttonColor: shrinePink100, scaffoldBackgroundColor: shrineBackgroundWhite, cardColor: shrineBackgroundWhite, textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100), errorColor: shrineErrorRed, buttonTheme: const ButtonThemeData( colorScheme: _shrineColorScheme, textTheme: ButtonTextTheme.normal, ), primaryIconTheme: _customIconTheme(base.iconTheme), textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), iconTheme: _customIconTheme(base.iconTheme), ); } IconThemeData _customIconTheme(IconThemeData original) { return original.copyWith(color: shrineBrown900); } TextTheme _buildShrineTextTheme(TextTheme base) { return base .copyWith( caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14, letterSpacing: defaultLetterSpacing, ), button: base.button.copyWith( fontWeight: FontWeight.w500, fontSize: 14, letterSpacing: defaultLetterSpacing, ), ) .apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrinePink50, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); // Placeholder definitions for Shrine theme colors and constants const Color shrinePink100 = Color(0xFFF8BBD0); const Color shrinePink50 = Color(0xFFFCE4EC); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Color(0xFFFFFFFF); const Color shrineErrorRed = Color(0xFFB00020); const double defaultLetterSpacing = 0.03; ``` -------------------------------- ### Flutter Switch Theming Example with Shrine Theme Source: https://github.com/material-components/material-components-flutter/blob/develop/docs/components/switches.md Demonstrates how to apply a custom Material Theme, specifically the Shrine theme, to Flutter Switches. This example includes a `Switch` widget within a `ListTile` and shows how to manage the switch's state and disable it. It also defines custom `ColorScheme`, `IconThemeData`, and `TextTheme` for the theme. ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, home: MyHomePage(), theme: _buildShrineTheme(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { List _values = [true, false, true, false, false]; Widget build(BuildContext context) { final int count = 4; return Scaffold( body: Column( children: [ for (int i = 0; i <= count; i++) ListTile( title: Text( 'Switch ${i + 1}', style: Theme.of(context).textTheme.subtitle1.copyWith( color: i == count ? Colors.black38 : Colors.black), ), leading: Switch( value: _values[i], onChanged: i == count ? null : (bool value) { setState(() { _values[i] = value; }); }, ), ), ], ), ); } } ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( colorScheme: _shrineColorScheme, toggleableActiveColor: shrinePink400, accentColor: shrineBrown900, primaryColor: shrinePink100, buttonColor: shrinePink100, scaffoldBackgroundColor: shrineBackgroundWhite, cardColor: shrineBackgroundWhite, textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100), errorColor: shrineErrorRed, buttonTheme: const ButtonThemeData( colorScheme: _shrineColorScheme, textTheme: ButtonTextTheme.normal, ), primaryIconTheme: _customIconTheme(base.iconTheme), textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), iconTheme: _customIconTheme(base.iconTheme), ); } IconThemeData _customIconTheme(IconThemeData original) { return original.copyWith(color: shrineBrown900); } TextTheme _buildShrineTextTheme(TextTheme base) { return base .copyWith( caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14, letterSpacing: defaultLetterSpacing, ), button: base.button.copyWith( fontWeight: FontWeight.w500, fontSize: 14, letterSpacing: defaultLetterSpacing, ), ) .apply( fontFamily: 'Rubik', displayColor: shrineBrown900, bodyColor: shrineBrown900, ); } const ColorScheme _shrineColorScheme = ColorScheme( primary: shrinePink100, primaryVariant: shrineBrown900, secondary: shrinePink50, secondaryVariant: shrineBrown900, surface: shrineSurfaceWhite, background: shrineBackgroundWhite, error: shrineErrorRed, onPrimary: shrineBrown900, onSecondary: shrineBrown900, onSurface: shrineBrown900, onBackground: shrineBrown900, onError: shrineSurfaceWhite, brightness: Brightness.light, ); const Color shrinePink50 = Color(0xFFFEEAE6); const Color shrinePink100 = Color(0xFFFEDBD0); const Color shrinePink300 = Color(0xFFFBB8AC); const Color shrinePink400 = Color(0xFFEAA4A4); const Color shrineBrown900 = Color(0xFF442B2D); const Color shrineBrown600 = Color(0xFF7D4F52); const Color shrineErrorRed = Color(0xFFC5032B); const Color shrineSurfaceWhite = Color(0xFFFFFBFA); const Color shrineBackgroundWhite = Colors.white; const defaultLetterSpacing = 0.03; ```