Working with TextButton in Flutter (2022)

Last updated on February 6, 2022 A Goodman Loading... 4 comments

Buttons are an essential component of every Flutter web and mobile application. In this article, we are going to take a look at the TextButton class. You will learn how to implement text buttons, and how to disable them. We will also cover what we can do to style and customize a text button. Without any further ado, let’s dive right in.

What is a TextButton?

A TextButton widget is just a text label displayed on a zero elevation Material widget. By default, it doesn’t have visible borders and reacts to touches by filling with a background color.

TextButton is the replacement for FlatButton which used to be a very popular widget but is now obsolete and you should no longer use it in new projects.

To get rid of annoying warnings or errors with TextButton, you should use Flutter 1.22.0 or newer. The examples in this article were recently updated to work properly with the most recent version of Flutter (2.8.1+).

TextButton Constructors

TextButton

TextButton({
  Key? key, 
  required VoidCallback? onPressed, 
  VoidCallback? onLongPress, 
  ValueChanged<bool>? onHover, 
  ValueChanged<bool>? onFocusChange, 
  ButtonStyle? style, 
  FocusNode? focusNode, 
  bool autofocus = false, 
  Clip clipBehavior = Clip.none, 
  required Widget child
})

Example:

TextButton(
    onPressed: () {},
    child: const Text('Simple Button'),
),

Screenshot:

TextButton with icon

TextButton.icon({
  Key? key, 
  required VoidCallback? onPressed, 
  VoidCallback? onLongPress, 
  ValueChanged<bool>? onHover, 
  ValueChanged<bool>? onFocusChange, 
  ButtonStyle? style, 
  FocusNode? focusNode, 
  bool? autofocus, 
  Clip? clipBehavior, 
  required Widget icon, 
  required Widget label
})

Example:

TextButton.icon(
    icon: const Icon(Icons.camera),
    label: const Text('Take A Photo'),
    onPressed: () {},
)

Screenshot:

How to disable a TextButton

A disabled button is a button that doesn’t react to touch. To disable a text button, just set onPressed and onLongPress to null (onLongPress is null by default).

Example:

Column(
        children: [
          TextButton(
            onPressed: null,
            child: const Text('Disabled Button'),
          ),
          TextButton(
            onPressed: () {},
            child: const Text('Enabled Button'),
          ),
          TextButton.icon(
              onPressed: null,
              icon: const Icon(Icons.room_rounded),
              label: const Text('Disabled Icon Button')),
          TextButton.icon(
              onPressed: () {},
              icon: const Icon(Icons.room_rounded),
              label: const Text('Enabled Icon Button'))
        ],
      ),

Screenshot:

How to style a TextButton

You can style a text button by using the TextButton.styleFrom static method or using the ButtonStyle class. The first approach is more convenient than the second one.

Using TextButton.styleFrom

All of the available options:

styleFrom({
  Color? primary, 
  Color? onSurface, 
  Color? backgroundColor, 
  Color? shadowColor, 
  double? elevation, 
  TextStyle? textStyle, 
  EdgeInsetsGeometry? padding, 
  Size? minimumSize, 
  Size? fixedSize, 
  Size? maximumSize, 
  BorderSide? side, 
  OutlinedBorder? shape, 
  MouseCursor? enabledMouseCursor, 
  MouseCursor? disabledMouseCursor, 
  VisualDensity? visualDensity, 
  MaterialTapTargetSize? tapTargetSize, 
  Duration? animationDuration, 
  bool? enableFeedback, 
  AlignmentGeometry? alignment, 
  InteractiveInkFeatureFactory? splashFactory
})

Example:

TextButton(
            onPressed: () {},
            child: const Text(
              'Text Button',
            ),
            style: TextButton.styleFrom(
                primary: Colors.purple,
                backgroundColor: Colors.amber,
                textStyle:
                    const TextStyle(fontSize: 24, fontStyle: FontStyle.italic)),
),

Screenshot:

Using ButtonStyle

Parameters:

ButtonStyle({
  MaterialStateProperty<TextStyle?>? textStyle, 
  MaterialStateProperty<Color?>? backgroundColor, 
  MaterialStateProperty<Color?>? foregroundColor, 
  MaterialStateProperty<Color?>? overlayColor, 
  MaterialStateProperty<Color?>? shadowColor, 
  MaterialStateProperty<double?>? elevation, 
  MaterialStateProperty<EdgeInsetsGeometry?>? padding, 
  MaterialStateProperty<Size?>? minimumSize, 
  MaterialStateProperty<Size?>? fixedSize, 
  MaterialStateProperty<Size?>? maximumSize, 
  MaterialStateProperty<BorderSide?>? side, 
  MaterialStateProperty<OutlinedBorder?>? shape, 
  MaterialStateProperty<MouseCursor?>? mouseCursor, 
  VisualDensity? visualDensity, 
  MaterialTapTargetSize? tapTargetSize, 
  Duration? animationDuration, 
  bool? enableFeedback, 
  AlignmentGeometry? alignment, 
  InteractiveInkFeatureFactory? splashFactory
})

Example:

TextButton(
              onPressed: () {},
              child: const Text(
                'Text Button',
              ),
              style: ButtonStyle(
                  side: MaterialStateProperty.all(
                      const BorderSide(width: 2, color: Colors.red)),
                  foregroundColor: MaterialStateProperty.all(Colors.purple),
                  padding: MaterialStateProperty.all(
                      const EdgeInsets.symmetric(vertical: 10, horizontal: 50)),
                  textStyle: MaterialStateProperty.all(
                      const TextStyle(fontSize: 30)))
),

Screenshot:

Styling The Child

If you only want to style the text, you can simply do like this:

TextButton(
            onPressed: () {},
            child: Text(
              'Text Button',
              style: TextStyle(fontSize: 30, color: Colors.red),
            ),
          ),

Screenshot:

TextButton Theming

Using theme allows you to style multiple text buttons at once.

Example:

// main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        // Remove the debug banner
        debugShowCheckedModeBanner: false,
        title: 'Kindacode.com',
        theme: ThemeData(
            primarySwatch: Colors.indigo,
            textButtonTheme: TextButtonThemeData(
                style: TextButton.styleFrom(
                    primary: Colors.red,
                    textStyle: const TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                        fontStyle: FontStyle.italic)))),
        home: const HomePage());
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextButton(onPressed: () {}, child: const Text('Text Button 1')),
            TextButton.icon(
                onPressed: () {},
                icon: const Icon(Icons.camera),
                label: const Text('Text Button 2'))
          ],
        ),
      ),
    );
  }
}

Output:

One More Example

The code in ./lib/main.dart:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('TextButton example'),
        backgroundColor: Colors.black,
      ),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(children: [
          /// Text Button #1
          TextButton(
              child: const Text(
                'Button #1',
              ),
              onPressed: () {
                debugPrint('Button #1 is clicked!');
              }),

          /// Text Button #2
          TextButton(
            child: const Text('Button #2',
                style: TextStyle(
                    color: Colors.red,
                    fontSize: 30,
                    fontWeight: FontWeight.bold)),
            onPressed: () {
              debugPrint('Button #2 is clicked');
            },
            onLongPress: () {
              debugPrint('Button #2 is long clicked!');
            },
          )
        ]),
      ),
    );
  }
}

The results on Android and iOS:

References

Afterword

This article went through the most important aspects of using text buttons in Flutter. You should avoid using text buttons where they would blend in with other content because they look like a link. If you’d like to learn more about Flutter, read also the following articles:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.

Subscribe
Notify of
guest
4 Comments
Inline Feedbacks
View all comments
Sanjay Sandhu
Sanjay Sandhu
1 year ago

Can you type the code for minimum size?

Koaki
Koaki
1 year ago
Reply to  A Goodman

Thanks so much

Related Articles