Dart Tutorial

Flutter Lesson 11 of 83 3 min read

Buttons in Flutter: FilledButton, ElevatedButton, TextButton and More

Learn every Flutter button: FilledButton, ElevatedButton, OutlinedButton, TextButton, IconButton and FloatingActionButton, with styling.

On this page

Flutter’s Material buttons differ in how much attention they demand. Use the strongest style for the one main action on a screen.

The button family #

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              FilledButton(onPressed: () {}, child: const Text('Filled')),
              FilledButton.tonal(onPressed: () {}, child: const Text('Tonal')),
              ElevatedButton(onPressed: () {}, child: const Text('Elevated')),
              OutlinedButton(onPressed: () {}, child: const Text('Outlined')),
              TextButton(onPressed: () {}, child: const Text('Text')),
              IconButton(onPressed: () {}, icon: const Icon(Icons.share)),
              const FilledButton(onPressed: null, child: Text('Disabled')),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {},
          child: const Icon(Icons.add),
        ),
      ),
    ),
  );
}
ButtonEmphasisTypical use
FilledButtonHighestThe main action: Save, Pay, Sign in
FilledButton.tonalHighAn important secondary action
ElevatedButtonMediumAn action that needs to stand out from a busy background
OutlinedButtonMediumSecondary: Cancel, Back
TextButtonLowDialog actions, links
IconButtonLowToolbar actions
FloatingActionButtonHighestThe one primary action of a screen

onPressed #

Every button needs onPressed. It is a function that runs on tap.

FilledButton(
  onPressed: () {
    debugPrint('Saved');
  },
  child: const Text('Save'),
)

FilledButton(onPressed: _save, child: const Text('Save')) // pass a method by name

Pass null to disable the button. It greys out and ignores taps.

FilledButton(
  onPressed: _isValid ? _submit : null,
  child: const Text('Submit'),
)

Icon and label #

FilledButton.icon(
  onPressed: () {},
  icon: const Icon(Icons.download),
  label: const Text('Download'),
)

ElevatedButton.icon, OutlinedButton.icon and TextButton.icon work the same way.

Styling one button #

Each button class has a styleFrom helper.

FilledButton(
  onPressed: () {},
  style: FilledButton.styleFrom(
    backgroundColor: Colors.deepPurple,
    foregroundColor: Colors.white,
    padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
    textStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
  ),
  child: const Text('Continue'),
)

A full-width button #

SizedBox(
  width: double.infinity,
  child: FilledButton(onPressed: () {}, child: const Text('Sign in')),
)

Or set minimumSize: const Size.fromHeight(48) in styleFrom.

Styling every button at once #

Set it in the theme, not on each button.

MaterialApp(
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
    filledButtonTheme: FilledButtonThemeData(
      style: FilledButton.styleFrom(
        minimumSize: const Size.fromHeight(48),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      ),
    ),
  ),
  home: const HomePage(),
)

A button that shows progress #

FilledButton(
  onPressed: _saving ? null : _save,
  child: _saving
      ? const SizedBox(
          width: 20,
          height: 20,
          child: CircularProgressIndicator(strokeWidth: 2),
        )
      : const Text('Save'),
)

Disabling the button while saving also stops double taps.

Good habits #

  • One filled button per screen. If everything shouts, nothing is heard.
  • Label with a verb that says what happens: “Send message”, not “OK”.
  • Give IconButton a tooltip. Screen readers use it.
  • Keep tap targets at least 48 by 48 logical pixels.

Try it yourself #

Build a row with a “Cancel” OutlinedButton and a “Save” FilledButton. Add a checkbox above them, and keep Save disabled until the box is ticked.

Practise in the playground Updated by Santosh Adhikari