Created
April 26, 2021 16:51
-
-
Save rydmike/c0eb2dbf71eac95083bc419eb20cdba0 to your computer and use it in GitHub Desktop.
Flutter experiment to better theme center text in Stadium Bordered buttons.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatefulWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
_MyAppState createState() => _MyAppState(); | |
} | |
class _MyAppState extends State<MyApp> { | |
ThemeMode themeMode = ThemeMode.light; | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
title: 'Flutter Demo', | |
theme: AppTheme.light, | |
darkTheme: AppTheme.dark, | |
themeMode: themeMode, | |
home: MyHomePage( | |
title: 'Flutter Demo Home Page', | |
onThemeMode: (ThemeMode mode) { | |
setState(() { | |
themeMode = mode; | |
}); | |
}, | |
), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
const MyHomePage({Key? key, required this.title, required this.onThemeMode}) | |
: super(key: key); | |
final String title; | |
final ValueChanged<ThemeMode> onThemeMode; | |
@override | |
// ignore: library_private_types_in_public_api | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
int _counter = 0; | |
bool _isDarkMode = false; | |
void _incrementCounter() { | |
setState(() { | |
_counter++; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
const Text( | |
'You have pushed the button this many times:', | |
), | |
Text( | |
'$_counter', | |
style: Theme.of(context).textTheme.headline4, | |
), | |
const SizedBox(height: 16), | |
ElevatedButton( | |
onPressed: _incrementCounter, | |
child: const Text('Donate here'), | |
), | |
const SizedBox(height: 16), | |
OutlinedButton( | |
onPressed: _incrementCounter, | |
child: const Text('Donate here'), | |
), | |
const SizedBox(height: 16), | |
TextButton( | |
onPressed: _incrementCounter, | |
child: const Text('Donate here'), | |
), | |
Switch.adaptive( | |
value: _isDarkMode, | |
onChanged: (bool value) { | |
setState(() { | |
_isDarkMode = value; | |
}); | |
if (_isDarkMode) { | |
widget.onThemeMode(ThemeMode.dark); | |
} else { | |
widget.onThemeMode(ThemeMode.light); | |
} | |
}, | |
), | |
], | |
), | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: _incrementCounter, | |
tooltip: 'Increment', | |
child: const Icon(Icons.add), | |
), | |
); | |
} | |
} | |
/// The theme for this app. | |
class AppTheme { | |
// This constructor prevents external instantiation and extension. | |
AppTheme._(); | |
/// The outline thickness of OutlinedButton. | |
static const double outlineThickness = 1.4; | |
/// Extra bottom padding for buttons. | |
static const double buttonBottomPadding = 1; | |
/// Light theme colors | |
static const Color primaryLight = Color(0xFF184782); | |
static const Color primaryVariantLight = Color(0xFF0E2B4E); | |
static const Color secondaryLight = Color(0xFFE59A18); | |
static const Color secondaryVariantLight = Color(0xFFF0B03F); | |
static const Color backgroundLight = Color(0xFFF9F9F9); | |
static const Color surfaceLight = Color(0xFFFBFBFB); | |
static const Color scaffoldBackgroundLight = Color(0xFFFDFDFD); | |
// Dark theme colors | |
static const Color primaryDark = Color(0xFF6098D3); | |
static const Color primaryVariantDark = Color(0xFF5F87B2); | |
static const Color secondaryDark = Color(0xFFEDBA62); | |
static const Color secondaryVariantDark = Color(0xFFEAB04D); | |
static const Color backgroundDark = Color(0xFF121517); | |
static const Color surfaceDark = Color(0xFF131517); | |
static const Color scaffoldBackgroundDark = Color(0xFF131517); | |
/// The used light theme. | |
static ThemeData get light { | |
return ThemeData.from( | |
colorScheme: colorSchemeLight, | |
textTheme: const TextTheme(), | |
).copyWith( | |
scaffoldBackgroundColor: scaffoldBackgroundLight, | |
toggleableActiveColor: colorSchemeLight.secondary, | |
elevatedButtonTheme: elevatedButtonTheme, | |
outlinedButtonTheme: outlinedButtonTheme(primaryLight), | |
textButtonTheme: textButtonTheme, | |
visualDensity: VisualDensity.standard, | |
); | |
} | |
/// Light theme color scheme. | |
static ColorScheme get colorSchemeLight => const ColorScheme.light().copyWith( | |
primary: primaryLight, | |
primaryVariant: primaryVariantLight, | |
secondary: secondaryLight, | |
secondaryVariant: secondaryVariantLight, | |
surface: surfaceLight, | |
background: backgroundLight, | |
); | |
/// The used dark theme. | |
static ThemeData get dark { | |
return ThemeData.from( | |
colorScheme: colorSchemeDark, | |
textTheme: const TextTheme(), | |
).copyWith( | |
scaffoldBackgroundColor: scaffoldBackgroundDark, | |
toggleableActiveColor: colorSchemeDark.secondary, | |
elevatedButtonTheme: elevatedButtonTheme, | |
outlinedButtonTheme: outlinedButtonTheme(primaryDark), | |
textButtonTheme: textButtonTheme, | |
visualDensity: VisualDensity.standard, | |
); | |
} | |
/// Dark theme color scheme. | |
static ColorScheme get colorSchemeDark => const ColorScheme.dark().copyWith( | |
primary: primaryDark, | |
primaryVariant: primaryVariantDark, | |
secondary: secondaryDark, | |
secondaryVariant: secondaryVariantDark, | |
); | |
/// From button migration guide, we use the past minimumSize & padding: | |
/// https://flutter.dev/docs/release/breaking-changes/buttons#migration-guide | |
/// Theme definition to give ElevatedButton a Stadium rounded design. | |
static ElevatedButtonThemeData get elevatedButtonTheme => | |
ElevatedButtonThemeData( | |
style: ElevatedButton.styleFrom( | |
shape: const StadiumBorder(), | |
minimumSize: const Size(88, 36), | |
padding: const EdgeInsets.fromLTRB(16, 0, 16, buttonBottomPadding), | |
), | |
); | |
/// Theme definition to give OutlinedButton a Stadium rounded design. | |
static OutlinedButtonThemeData outlinedButtonTheme(Color borderColor) => | |
OutlinedButtonThemeData( | |
style: OutlinedButton.styleFrom( | |
shape: const StadiumBorder(), | |
minimumSize: const Size(88, 36), | |
padding: const EdgeInsets.fromLTRB(16, 0, 16, buttonBottomPadding), | |
side: BorderSide( | |
color: borderColor, | |
width: outlineThickness, | |
), | |
), | |
); | |
/// Theme definition to give TextButton a Stadium rounded design. | |
static TextButtonThemeData get textButtonTheme => TextButtonThemeData( | |
style: TextButton.styleFrom( | |
shape: const StadiumBorder(), | |
minimumSize: const Size(88, 36), | |
padding: const EdgeInsets.fromLTRB(16, 0, 16, buttonBottomPadding), | |
), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment