A Comprehensive Guide to Flutter Buttons: Choosing the Right One for Your App
Are you a Flutter developer who’s ever felt puzzled by which button to use in your app’s UI? You’re not alone. Many developers struggle to pick the right button type, often resorting to unnecessary customizations. But fear not! This guide is here to demystify Flutter buttons, helping you make informed choices for your app’s design needs.
- Basic TextButton with onPressed function enabled
- Disabled TextButton with onPressed function set to null
- TextButton with icon and onPressed function enabled
- TextButton with custom styling and onPressed function enabled
- TextButton with custom shape and onPressed function enabled
- TextButton with custom overlay color and onPressed function enabled
- TextButton with custom foreground using ShaderMask and onPressed function enabled
- TextButton with custom foreground using DecoratedBox and onPressed function enabled
- TextButton with custom background and onPressed function enabled
TextButton:
The TextButton is your basic, no-frills button. It’s perfect for simple actions like navigating pages or confirming choices. Avoid adding unnecessary customizations to it. Let it blend seamlessly into your UI, or customize it with a style or theme if needed.
Basic TextButton with onPressed function enabled
TextButton(
// onPressed function that gets triggered when button is pressed
onPressed: () {
// Add your onPressed code here!
},
child: const Text(
'This is a TextButton Demo - Enabled',
), // Text displayed on the button
),
Disabled TextButton with onPressed function set to null
TextButton(
// Button is disabled
// as onPressed function is null
onPressed: null,
child: Text(
'This is a TextButton Demo - Disabled',
),
),
TextButton with icon and onPressed function enabled
TextButton.icon(
// onPressed function that gets
//triggered when button is pressed
onPressed: () {
// Add your onPressed code here!
},
icon: const Icon(
Icons.access_alarm,
), // Icon displayed before the text
label: const Text(
'This is a TextButton Demo - TextButton.icon #1',
), // Text displayed on the button
),
TextButton with custom styling and onPressed function enabled
TextButton.icon(
style: TextButton.styleFrom(
foregroundColor: Colors.white, // Text color
backgroundColor: Colors.green, // Background color
),
onPressed: () {}, // onPressed function that gets triggered when button is pressed
icon: const Icon(
Icons.access_alarm,
), // Icon displayed before the text
label: const Text(
'This is a TextButton Demo - TextButton.icon #2',
), // Text displayed on the button
),
TextButton with custom shape and onPressed function enabled
TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: const BorderRadius.all(
Radius.circular(
20,
),
), // Border radius of the button
side: BorderSide(
color: Colors.lightBlue, // Border color
width: 3, // Border width
),
),
),
onPressed: () {}, // onPressed function that gets triggered when button is pressed
child: const Text(
'This is a TextButton Demo - TextButton #3',
), // Text displayed on the button
),
TextButton with custom overlay color and onPressed function enabled
TextButton(
style: TextButton.styleFrom(
overlayColor: Colors.amber, // Color when button is pressed
),
onPressed: () {}, // onPressed function that gets triggered when button is pressed
child: const Text(
'This is a TextButton Demo - TextButton #4',
), // Text displayed on the button
),
TextButton with custom foreground using ShaderMask and onPressed function enabled
TextButton(
style: TextButton.styleFrom(
foregroundBuilder: (context, states, child) {
return ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.red,
Colors.green,
],
).createShader(bounds);
},
blendMode: BlendMode.srcATop,
child: child,
);
},
),
onPressed: () {}, // onPressed function that gets triggered when button is pressed
child: const Text(
'This is a TextButton Demo - TextButton #5',
), // Text displayed on the button
),
TextButton with custom foreground using DecoratedBox and onPressed function enabled
TextButton(
style: TextButton.styleFrom(
foregroundBuilder: (context, states, child) {
return DecoratedBox(
decoration: BoxDecoration(
border: states.contains(MaterialState.hovered)
? Border(
bottom: BorderSide(
color: Colors.lightBlue,
),
)
: const Border(), // Border displayed when button is hovered
),
child: child,
);
},
),
onPressed: () {}, // onPressed function that gets triggered when button is pressed
child: const Text(
'This is a TextButton Demo - TextButton #6',
), // Text displayed on the button
),
TextButton with custom background and onPressed function enabled
TextButton(
onPressed: () {}, // onPressed function that gets triggered when button is pressed
style: TextButton.styleFrom(
overlayColor: Colors.orange.withOpacity(
1.0,
), // Color when button is pressed
backgroundBuilder: (context, states, child) {
return AnimatedContainer(
duration: const Duration(
milliseconds: 500,
), // Duration of the animation
decoration: (states.contains(MaterialState.pressed))
? BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.orange.withOpacity(
1.0,
),
Colors.orange.withOpacity(
1.0,
),
],
), // Gradient when button is pressed
)
: BoxDecoration(
gradient: LinearGradient(
colors: switch (
states.contains(MaterialState.hovered)) {
true => [
Colors.blue.withOpacity(
1.0,
),
Colors.orange.withOpacity(
1.0,
)
],
false => [
Colors.orange.withOpacity(
1.0,
),
Colors.blue.withOpacity(
1.0,
),
],
},
), // Gradient when button is not pressed
),
child: child,
);
},
).copyWith(
side: MaterialStateProperty.resolveWith<BorderSide?>((states) {
if (states.contains(MaterialState.hovered)) {
return BorderSide(
width: 3,
color: Colors.yellow.withOpacity(
1.0,
), // Border color when button is hovered
);
}
return null; // Border color when button is not hovered
}),
),
child: const Text(
'TextButton #7',
style: TextStyle(
color: Colors.white,
),
), // Text displayed on the button
),
FilledButton:
Consider FilledButton as a TextButton with a bit more flair. It’s great for important actions that demand attention, like saving or confirming. While it offers tonal variations, remember, it’s essentially a styled TextButton.
A filled button with a solid background color
FilledButton(
onPressed: () {
// Define the action that should be taken when the button is pressed.
// Currently, this is an empty function.
},
child: const Text(
"This is a filled button - Mihir Pipermitwala",
),
),
A tonal filled button with background color
FilledButton.tonal(
onPressed: () {
// Define the action that should be taken when the button is pressed.
// Currently, this is an empty function.
},
child: const Text(
"This is a filled button (tonal)",
),
)
ElevatedButton:
ElevatedButton adds depth to your UI with its elevation and native Android-like appearance. Use it when you want your button to stand out or convey hierarchy. But avoid using it in popups or dialogues where default animations might clash.
A Disabled ElevatedButton with custom text style
ElevatedButton(
onPressed: null,
child: const Text(
'Disabled',
),
),
ElevatedButton(
onPressed: () {
// Add your onPressed code here!
},
child: const Text(
'Enabled',
),
),
OutlinedButton:
If you need a button with a subtle outline, OutlinedButton is your friend. It’s ideal for medium-emphasis actions. Its clean design ensures it doesn’t overpower your UI elements.
OutlinedButton with a custom onPressed callback
OutlinedButton(
onPressed: () {
debugPrint(
'Received click',
);
},
child: const Text(
'Click Me',
),
),
IconButton:
Need a button with just an icon? IconButton is the way to go. It offers click animations and various button styles, making it versatile for different UI needs.
Basic IconButton with an icon and onPressed function
IconButton(
icon: const Icon(Icons.filter_drama),
onPressed: () {
// Add your onPressed code here!
},
),
Filled IconButton with an icon and onPressed function
IconButton.filled(
onPressed: () {
// Add your onPressed code here!
},
icon: const Icon(
Icons.filter_drama,
),
),
Filled tonal IconButton with an icon and onPressed function
IconButton.filledTonal(
onPressed: () {
// Add your onPressed code here!
},
icon: const Icon(
Icons.filter_drama,
),
),
Outlined IconButton with an icon and onPressed function
IconButton.outlined(
onPressed: () {
// Add your onPressed code here!
},
icon: const Icon(
Icons.filter_drama,
),
),
FloatingActionButton:
The FloatingActionButton (FAB) widget is a circular button that floats above the content in a Flutter application. It is typically used for a primary action in an application.
Small FloatingActionButton with an add icon
FloatingActionButton.small(
onPressed: () {
// Add your onPressed code here!
},
child: const Icon(Icons.add),
),
Default size FloatingActionButton with an add icon
FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
child: const Icon(Icons.add),
),
Large FloatingActionButton with an add icon
FloatingActionButton.large(
onPressed: () {
// Add your onPressed code here!
},
child: const Icon(Icons.add),
),
Extended FloatingActionButton with a label and an add icon
FloatingActionButton.extended(
onPressed: () {
// Add your onPressed code here!
},
label: const Text('Add'),
icon: const Icon(Icons.add),
),
CupertinoButton:
CupertinoButton brings an iOS-native button design to your Flutter app. Use it for a seamless iOS experience, complete with default iOS animations and padding.
A disabled Cupertino button with a standard transparent background
const CupertinoButton(
onPressed: null,
child: Text('Disabled'),
),
A disabled filled Cupertino button with a solid background color
const CupertinoButton.filled(
onPressed: null,
child: Text('Disabled'),
),
An enabled Cupertino button with a standard transparent background
CupertinoButton(
onPressed: () {
// Define the action that should be taken when the button is pressed.
},
child: const Text('Enabled'),
),
An enabled filled Cupertino button with a solid background color
CupertinoButton.filled(
onPressed: () {
// Define the action that should be taken when the button is pressed.
},
child: const Text('Enabled'),
),
Summary
Each Flutter button serves a specific purpose in your UI arsenal. Choose wisely based on your app’s needs, and remember, simplicity is often key. Have questions or suggestions? Drop them in the comments below. And if you found this guide helpful, don’t forget to show some love by hitting that clap button!