Style an ElevatedButton with styleFrom and themes
ElevatedButton takes a ButtonStyle, and building one by hand is verbose. ElevatedButton.styleFrom takes plain values and does it for you:
return ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.indigo,
disabledBackgroundColor: Colors.grey.shade300,
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(horizontal: 32),
),
onPressed: onPressed,
child: const Text('Checkout'),
);- plain values in, a full ButtonStyle out
styleFrom fills in the states for you, too: disabledBackgroundColor is used when onPressed is null, and the pressed and hover overlays are derived from foregroundColor.
Style every button at once
Copying that style onto each button doesn’t scale. Put it in the theme:
return MaterialApp(
theme: ThemeData(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
backgroundColor: Colors.amber,
),
),
),
home: home,
);- applies to buttons without their own style
Every ElevatedButton without its own style now picks it up. A local style still wins, property by property: a button that only sets backgroundColor keeps the theme’s foregroundColor.
Styles that depend on state
When one property should differ per state, build a ButtonStyle with WidgetStateProperty:
final pressableStyle = ButtonStyle(
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.disabled)) return Colors.grey;
if (states.contains(WidgetState.pressed)) return Colors.indigo;
return Colors.indigo.shade300;
}),
foregroundColor: const WidgetStatePropertyAll(Colors.white),
);- called with the current states on every change
resolveWith gets the current set of WidgetStates: pressed, hovered, focused, disabled and so on. Check the most specific ones first. For a value that never changes, WidgetStatePropertyAll saves you the function.
The test for this tip presses the button and checks that the painted color changes, then disables it and checks again.
Migrating older code
MaterialStateProperty and MaterialState are the old names. They’re deprecated aliases of WidgetStateProperty and WidgetState, so a find and replace is all it takes. Older still, RaisedButton and its color parameter are gone; ElevatedButton with styleFrom is the replacement.
Adapted from tip #11 in Flutter Tips & Tricks by Andrea Bizzotto (MIT). Updated for current Flutter. Not affiliated with or endorsed by the original author. Suggest an edit.