Buttons in Flutter: A Complete Guide to Button Widgets and Styles

- Andrés Cruz - ES En español

In the previous post, we talked about how to install Flutter and create our first application, what IDEs we can use—basically Android Studio and/or Visual Studio Code—and we also gave an introduction to the world of widgets in Flutter by creating a card (Card) with content, text, and images, which are also widgets. If you want to review it, you can go to the following link:

Getting started with Flutter from scratch: My first application.

Today we will continue working with Flutter, but this time we will focus on an essential element in any interface: the button. In Flutter, buttons are specialized widgets for processing user actions, and they fit perfectly with the Card widgets we saw earlier. Knowing the different types of button widgets in Flutter will allow you to choose the right one according to the context and design of your application.

Buttons in Flutter: types and when to use each one

Flutter, as a modern and constantly evolving framework, offers us a wide variety of flutter buttons ready to use in our applications. In this post, I present the main types of buttons available and how you can take advantage of them. There are other more specific buttons, such as the ButtonBar, but we will not cover it here as it functions more like a container for buttons than an independent button.

Below, I present the most interesting buttons you can use in your application along with a practical summary of each. Ideally, you should use this content as a reference and test the buttons yourself in your projects, exploring all the properties you can configure beyond just the ones mentioned here.

FloatingActionButton: Floating Action Button in Flutter

The first button we will see is the famous Floating Action Button (FAB), an iconic element of Material Design that we can easily implement in Flutter using the FloatingActionButton widget:

 FloatingActionButton(    child: Icon(Icons.access_time),    elevation: 50.0,    backgroundColor: Colors.amber,  ),

With this widget, we create a floating action button; we can set a background color using backgroundColor—such as the soft orange in the example—assign an icon with the child property, and even adjust the elevation to control the shadow, a fundamental aspect in Material Design.

Remember that in Flutter, all interface elements are widgets. The FloatingActionButton is no exception: it does not position itself automatically in a corner of the screen as in native Android; instead, we must position it ourselves, for example, using the floatingActionButton property of the Scaffold.

FloatingActionButton floating action button in Flutter

To handle the action when pressing any button in Flutter, we use the onPressed property. Let's see a basic example with a RaisedButton:

RaisedButton(
 child: Text("Back"),
 onPressed: () => Navigator.pop(context),
)

The onPressed property is available on all Flutter buttons. To learn about all the specific properties for each type of button, you can consult the official documentation or take advantage of the autocompletion in Android Studio or Visual Studio Code.

RaisedButton in Flutter: the classic elevated button

The RaisedButton is the classic elevated button in Flutter, equivalent to the default Button we know in native Android. It allows customizing properties such as background color (color), the visual effect when pressed (splashColor), and, of course, the text using a Text widget:

RaisedButton( disabledColor: Colors.amber, child: Text("Raised Button"), splashColor: Colors.amber, color: Colors.blueAccent, onPressed: ()  {   print("Hello Raised Button") }, ),

In the previous example, you can see several properties in action, although these are not all that are available. We defined the button color with color, the text using a Text widget, the splash color, and an anonymous function for the click event in onPressed. For a full list of properties, check the official documentation.

RaisedButton in Flutter with color and splash properties

FlatButton in Flutter: flat button without background

The FlatButton is a simple button without elevation, similar to the style of buttons in iOS. It is ideal when you want a subtle action that doesn't draw too much visual attention. You can modify aspects like typography, color, and size; but notice that, unlike other buttons, the FlatButton does not have a background color by default:

FlatButton(    child: new Text('Flat Button'), )
FlatButton in Flutter, flat button without background

MaterialButton in Flutter: button for Material Design

The MaterialButton is a button designed specifically to follow Google's Material Design guidelines. It is the current standard for modern Android applications. With just a few lines of code, you can create a button with a professional and consistent look:

MaterialButton(
    minWidth: 200.0,
    height: 40.0,
    onPressed: () {},
    color: Colors.lightBlue,
    child: Text('Material Button', style: TextStyle(color: Colors.white)),
  ),

With this code, we get a blue button that includes the characteristic Material Design ripple effect. For almost all buttons, we can define their dimensions using minWidth and height, in addition to text color, background color, and the rest of the properties you see here. For the full list, you can consult the official documentation or check directly from the IDE.

Which button to choose in Flutter?

As you can see, there is a button for every situation. Here is a quick guide to help you choose the right one:

  • If you don't have much space and want to highlight a primary action, use a FloatingActionButton.
  • If you need a well-designed button that follows Material Design guidelines, use a MaterialButton.
  • For a subtle button that doesn't attract attention, use a FlatButton or an IconButton.
  • For a classic elevated design, a RaisedButton will work well.

Below, you'll find the complete application code so you can run it yourself and perform all the tests you want:

MaterialButton in Flutter with ripple effect
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MiLista2'),
        ),
        body: Card(
          child: Center(
            child: Column(
              children: <Widget>[
                Image.asset('assets/codeigniter.png'),
                Text("Curso en CodeIgniter"),
                IconButton(
                  icon: Icon(Icons.access_alarms),
                  tooltip: "Mensaje",
                ),
                FloatingActionButton(
                  child: Icon(Icons.access_time),
                  elevation: 50.0,
                  backgroundColor: Colors.amber,
                ),
                MaterialButton(
                  minWidth: 200.0,
                  height: 40.0,
                  onPressed: () {},
                  color: Colors.lightBlue,
                  child: Text('Material Button',
                      style: TextStyle(color: Colors.white)),
                ),
                RaisedButton(
                  disabledColor: Colors.amber,
                  child: Text("Raised Button"),
                  splashColor: Colors.amber,
                  color: Colors.blueAccent,
                  onPressed: ()  {
                    print("Hola Raised Button");
                  },
                ),
                FlatButton(
                  child: new Text('Flat Button'),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Our application shows the different buttons that you can see in the promotional image.

Of course, here are links to the official documentation for each type of button:

From RaisedButton to ElevatedButton in Flutter: migration guide

Video thumbnail

As of Flutter 2, the widget RaisedButton was deprecated and replaced by ElevatedButton. Below I show you how to perform this migration in a simple way. Let's remember that a typical RaisedButton looks like this:

RaisedButton(
             color: Colors.purple,
             textColor: Colors.white,
             onPressed: () {
               // do something
             },
             child: Text("Go to page two"),
         ),

We generally define the background color with color and the text color with textColor.

When migrating to ElevatedButton, we can no longer define style properties directly as constructor parameters. Instead, all visual customization is concentrated in a single property called style:

 ElevatedButton(
             style: ###YOUR STYLE###
             child: Text("Go to page one"),
),

Defining the style of ElevatedButton with styleFrom

With the ElevatedButton.styleFrom() method, we can create a ButtonStyle object to customize our button easily and clearly:

final ButtonStyle raisedButtonStyle = ElevatedButton.styleFrom(
   onPrimary: Colors.white,
   primary: Colors.purple,
   padding: EdgeInsets.symmetric(horizontal: 16),
);

Then we pass it to the style property. With this, we make the ElevatedButton work similarly to the old RaisedButton:

  • With primary, we define the background color of the button.
  • With onPrimary, we control the text color and the ripple effect.
ElevatedButton(
             style: raisedButtonStyle,
             onPressed: () {
               // do something
             },
             child: Text("Go to page one"),
),

FloatingActionButton in Flutter: four available sizes

The FloatingActionButton is a Flutter widget that provides a circular floating button, commonly used for primary or secondary actions in an application. This button can contain an icon or text, and it floats above other interface elements. Its visual design automatically adapts to the platform on which the application runs, and it is frequently combined with other widgets such as Scaffold and AppBar.

One of the most recent additions in Flutter is the ability to define the size of the FloatingActionButton using named constructors. This allows us to choose between four variants:

4 types of FloatingActionButton in Flutter: extended, large, regular, and small
4 Floating type buttons for Flutter

Extended Floating Button (extended)

FloatingActionButton.extended(
           onPressed: () {}, label: Text("Extended")),

Large FloatingActionButton (large)

FloatingActionButton.large(
         child: Icon(Icons.plus_one),
         onPressed: (){
       }),

Regular FloatingActionButton (default constructor)

 floatingActionButton: FloatingActionButton(
         child: Icon(Icons.plus_one),
         onPressed: (){
       }),

Small floating button (small)

floatingActionButton: FloatingActionButton.small(
         child: Icon(Icons.plus_one),
         onPressed: (){
       }),

Conclusions on FAB sizes

  • The regular button is the standard (default constructor), so you don't need to specify any named constructor.
  • The extended button requires the label parameter (usually a Text). The rest of the variants follow the standard pattern of defining a child for the icon and any additional aspects you want to customize.

How to change the position of the FloatingActionButton in Flutter (2 ways)

Video thumbnail

I want to show you how you can change the location of your Floating Action Button (FAB) in Flutter. You can position it on the right, center, or left according to your design needs. Let's look at the two main ways to achieve this.

First way: using FloatingActionButtonLocation

The most direct way is to use the floatingActionButtonLocation property of the Scaffold:

Scaffold(
 floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
 ...
)

This allows you to quickly set the position of the FAB: center, left, or right. This is the recommended approach by official Flutter documentation and works well in most cases, although it may have limitations on very small screens.

Second way: using Column and Row for total control

If you need more flexibility, you can position the FAB manually using Column and Row. In this approach, your FAB is no longer a standalone button, but a composite widget that can include multiple elements, such as columns, additional buttons, or custom content.

Example implementation with columns:

enum FABPosition { left, right, center }
if (appModel.fabposition == FABPosition.center.toString()) {
 _floatingActionButtonLocation = MainAxisAlignment.center;
 _floatingActionButtonLocationCross = CrossAxisAlignment.center;
} else if (appModel.fabposition == FABPosition.left.toString()) {
 _floatingActionButtonLocation = MainAxisAlignment.start;
 _floatingActionButtonLocationCross = CrossAxisAlignment.start;
}

Then, in the Scaffold:

Scaffold(
 floatingActionButton: Padding(
   padding: const EdgeInsets.only(left: 30),
   child: Column(
     crossAxisAlignment: _floatingActionButtonLocationCross,
     mainAxisAlignment: MainAxisAlignment.end,
     children: [
       widget.showLastCourseWidget && appModel.showLastCourseWidget
           ? lastClassViewInCourse()
           : const SizedBox(),
       const SizedBox(height: 10),
       fab ?? const SizedBox(),
     ],
   ),
 ),
)

Explanation of the structure

  • MainAxisAlignment and CrossAxisAlignment control the horizontal and vertical alignment of the FAB.
  • The variables _floatingActionButtonLocationCross and _floatingActionButtonLocation determine if the button is on the left, right, or center depending on the user's settings.
  • Padding is used to adjust the spacing of the FAB relative to the screen edges.
  • Column allows you to stack multiple widgets, such as a shortcut to the last course (lastClassViewInCourse()) and the main FAB.

Summary and recommendations

  • The standard way is to use FloatingActionButtonLocation, provided by Flutter, to quickly position the FAB.
  • If you need more control or are using custom widgets, use Column and align using MainAxisAlignment and CrossAxisAlignment.
  • On small screens, the standard method may not work properly; the Column approach offers greater flexibility.
  • With this system, you can define dynamic positions based on user configuration.

How to update the previous page when using the back button in Flutter?

When working with CRUD operations in any framework, upon finishing a creation or update process, we usually return automatically to the listing page, where the changes made should be reflected. In Flutter, it might not be entirely clear how to achieve this update for the list view; we are not talking about triggering a function when clicking the back button (which would only affect the current page), but executing code after returning.

Navigation and the then method in Flutter

Remember that to navigate from one page to another, we use Flutter's Navigator class. What might not be as clear is that we can intercept the return of the navigation through the then function, which works like a promise (Future) and executes when the second page is closed:

ListTile(
          title: Text(notes[i].title),
          trailing: MaterialButton(
            onPressed: () => Navigator.pushNamed(context, SavePage.ROUTE,
                    arguments: notes[i])
                .then((value) => setState(() {
                      _loadData();
                    })),
            child: Icon(Icons.edit),
          )),

In our example, the _loadData() function reloads the list data. It is the same function we use to initially load the data, ensuring the view is always updated upon returning.

Next step, learn how to use the Card Widget in Flutter.

Discover all the button types in Flutter: RaisedButton, FlatButton, MaterialButton, and FloatingActionButton. A step-by-step guide covering code, positioning, and customization.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

I agree to receive announcements of interest about this Blog.