| // Copyright 2014 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import 'package:flutter/material.dart'; | |
| void main() { | |
| runApp(const ThemeDataExampleApp()); | |
| } | |
| // This app's theme specifies an overall ColorScheme as well as overrides | |
| // for the default configuration of FloatingActionButtons. To customize | |
| // the appearance of other components, add additional component specific | |
| // themes, rather than tweaking the color scheme. | |
| // | |
| // Creating an entire color scheme from a single seed color is a good | |
| // way to ensure a visually appealing color palette where the default | |
| // component colors have sufficient contrast for accessibility. Another | |
| // good way to create an app's color scheme is to use | |
| // ColorScheme.fromImageProvider. | |
| // | |
| // The color scheme reflects the platform's light or dark setting | |
| // which is retrieved with `MediaQuery.platformBrightnessOf`. The color | |
| // scheme's colors will be different for light and dark settings although | |
| // they'll all be related to the seed color in both cases. | |
| // | |
| // Color scheme colors have been used where component defaults have | |
| // been overridden so that the app will look good and remain accessible | |
| // in both light and dark modes. | |
| // | |
| // Text styles are derived from the theme's textTheme (not the obsolete | |
| // primaryTextTheme property) and then customized using copyWith. | |
| // Using the _on_ version of a color scheme color as the foreground, | |
| // as in `tertiary` and `onTertiary`, guarantees sufficient contrast | |
| // for readability/accessibility. | |
| class ThemeDataExampleApp extends StatelessWidget { | |
| const ThemeDataExampleApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| final ColorScheme colorScheme = ColorScheme.fromSeed( | |
| brightness: MediaQuery.platformBrightnessOf(context), | |
| seedColor: Colors.indigo, | |
| ); | |
| return MaterialApp( | |
| title: 'ThemeData Demo', | |
| theme: ThemeData( | |
| colorScheme: colorScheme, | |
| floatingActionButtonTheme: FloatingActionButtonThemeData( | |
| backgroundColor: colorScheme.tertiary, | |
| foregroundColor: colorScheme.onTertiary, | |
| ), | |
| ), | |
| home: const Home(), | |
| ); | |
| } | |
| } | |
| class Home extends StatefulWidget { | |
| const Home({super.key}); | |
| @override | |
| State<Home> createState() => _HomeState(); | |
| } | |
| class _HomeState extends State<Home> { | |
| int buttonPressCount = 0; | |
| @override | |
| Widget build(BuildContext context) { | |
| final ThemeData theme = Theme.of(context); | |
| final ColorScheme colorScheme = theme.colorScheme; | |
| final double pointCount = 8 + (buttonPressCount % 6); | |
| return Scaffold( | |
| appBar: AppBar(title: const Text('Press the + Button')), | |
| // An AnimatedContainer makes the decoration changes entertaining. | |
| body: AnimatedContainer( | |
| duration: const Duration(milliseconds: 500), | |
| margin: const .all(32), | |
| alignment: .center, | |
| decoration: ShapeDecoration( | |
| color: colorScheme.tertiaryContainer, | |
| shape: StarBorder( | |
| points: pointCount, | |
| pointRounding: 0.4, | |
| valleyRounding: 0.6, | |
| side: BorderSide(width: 9, color: colorScheme.tertiary), | |
| ), | |
| ), | |
| child: Text( | |
| '${pointCount.toInt()} Points', | |
| style: theme.textTheme.headlineMedium!.copyWith( | |
| color: colorScheme.onPrimaryContainer, | |
| ), | |
| ), | |
| ), | |
| floatingActionButton: FloatingActionButton( | |
| onPressed: () { | |
| setState(() { | |
| buttonPressCount += 1; | |
| }); | |
| }, | |
| tooltip: "Change the shape's point count", | |
| child: const Icon(Icons.add), | |
| ), | |
| ); | |
| } | |
| } |