Skip to content

Instantly share code, notes, and snippets.

@rydmike
Created April 26, 2021 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rydmike/c0eb2dbf71eac95083bc419eb20cdba0 to your computer and use it in GitHub Desktop.
Save rydmike/c0eb2dbf71eac95083bc419eb20cdba0 to your computer and use it in GitHub Desktop.
Flutter experiment to better theme center text in Stadium Bordered buttons.
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