| // 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 overidden 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 EdgeInsets.all(32), |
| alignment: 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), |
| ), |
| ); |
| } |
| } |