Flutter - Using SelectionArea Widget Examples

This tutorial shows you how to use the SelectionArea widget in Flutter.

SelectionArea is a widget that creates an area that allows user selections. It can be useful if you want to make the widgets of a subtree selectable by the users. In addition to providing the selection capability, it also allows the application developers to customize the selection control and appearance. Below I'm going to explain how to use it and what you can do with the widget.

Using SelectionArea

The constructor of the widget can be seen below.

  const SelectionArea({
    Key? key,
    FocusNode? focusNode,
    TextSelectionControls? selectionControls,
    Widget Function(BuildContext, SelectableRegionState)? contextMenuBuilder = _defaultContextMenuBuilder,
    TextMagnifierConfiguration? magnifierConfiguration,
    void Function(SelectedContent?)? onSelectionChanged,
    required Widget child,
  });

For the basic usage, you are only required to pass the child argument which is the widget whose content is selectable. You can pass any widget for it.

  SelectionArea(
    child: const Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Woolha'),
        Text('dot'),
        Text('com'),
      ],
    ),
    // other arguments
  )

Flutter - SelectionArea

Set Selection Controls

By default, when the selection is not empty, Flutter will show a selection control toolbar with several actions such as copy. The toolbar displayed by default depends on the platform where the Flutter application runs. For example, Flutter will show a Cupertino-styled one on iOS. On Android, it will use Material-styled. If you want to override the default toolbar, you can set it explicitly by passing a TextSelectionControls object as the selectionControls argument.

  SelectionArea(
    selectionControls: CupertinoTextSelectionControls(),
    // other arguments
  )

Flutter - SelectionArea - Selection Controls

Set Context Menu Builder

If you need to have a custom toolbar with different actions, you can pass a function that returns a widget as the contextMenuBuilder argument. The function needs to have two parameters. The first one is the BuildContext, while the other is SelectableRegionState.

Unless you need to have a completely different layout, you can use AdaptiveTextSelectionToolbar.buttonItems to build the widget. It requires you to create several ContextMenuButtonItem widgets where you can define the type and action of each button item.

  SelectionArea(
    contextMenuBuilder: (
      BuildContext context,
      SelectableRegionState selectableRegionState,
    ) {
      return AdaptiveTextSelectionToolbar.buttonItems(
        buttonItems: <ContextMenuButtonItem>[
          ContextMenuButtonItem(
            onPressed: () {
              selectableRegionState
                  .copySelection(SelectionChangedCause.toolbar);
            },
            type: ContextMenuButtonType.copy,
          ),
          ContextMenuButtonItem(
            onPressed: () {
              selectableRegionState.selectAll(SelectionChangedCause.toolbar);
            },
            type: ContextMenuButtonType.selectAll,
          ),
          ContextMenuButtonItem(
            onPressed: () {
              // Other action
            },
            type: ContextMenuButtonType.custom,
            label: 'Like',
          ),
        ],
        anchors: selectableRegionState.contextMenuAnchors,
      );
    },
    // other arguments
  )

Flutter - SelectionArea - Context Menu Builder

Handle Selection Changes

Every time the user changes the selection, you can get the latest selected text by passing a function as the onSelectionChanged argument. The passed function must have a parameter whose type is SelectedContent. You can get the value by accessing its plainText property.

SelectionArea Parameters

  • Key? key: The widget's key, used to control how a widget is replaced with another.
  • FocusNode? focusNode: Focus node of the widget.
  • TextSelectionControls? selectionControls: The delegate to build the selection handles and toolbar.
  • Widget Function(BuildContext, SelectableRegionState)? contextMenuBuilder = _defaultContextMenuBuilder: Function to return a text selection toolbar widget when requested by the user.
  • TextMagnifierConfiguration? magnifierConfiguration: Configuration for magnifier.
  • void Function(SelectedContent?)? onSelectionChanged: Function to be called when the selection changes.
  • required Widget child: The widget where the selection area is applied to.

Full Code

  import 'package:flutter/cupertino.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter/rendering.dart';
  
  void main() => runApp(const MyApp());
  
  class MyApp extends StatelessWidget {
  
    const MyApp({super.key});
  
    @override
    Widget build(BuildContext context) {
      return const MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: MyPage(),
        debugShowCheckedModeBanner: false,
      );
    }
  }
  
  class MyPage extends StatefulWidget {
  
    const MyPage({super.key});
  
    @override
    State<StatefulWidget> createState() {
      return MyPageState();
    }
  }
  
  class MyPageState extends State<MyPage> {
  
    String? _selectedContent;
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
          backgroundColor: Colors.teal,
        ),
        body: SizedBox(
          width: double.infinity,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              SelectionArea(
                selectionControls: CupertinoTextSelectionControls(),
                contextMenuBuilder: (
                  BuildContext context,
                  SelectableRegionState selectableRegionState,
                ) {
                  return AdaptiveTextSelectionToolbar.buttonItems(
                    buttonItems: <ContextMenuButtonItem>[
                      ContextMenuButtonItem(
                        onPressed: () {
                          selectableRegionState
                              .copySelection(SelectionChangedCause.toolbar);
                        },
                        type: ContextMenuButtonType.copy,
                      ),
                      ContextMenuButtonItem(
                        onPressed: () {
                          selectableRegionState.selectAll(SelectionChangedCause.toolbar);
                        },
                        type: ContextMenuButtonType.selectAll,
                      ),
                      ContextMenuButtonItem(
                        onPressed: () {
                          // Other action
                        },
                        type: ContextMenuButtonType.custom,
                        label: 'Like',
                      ),
                    ],
                    anchors: selectableRegionState.contextMenuAnchors,
                  );
                },
                onSelectionChanged: (SelectedContent? selectedContent) {
                  print('Selected content: ${selectedContent?.plainText}');
                  setState(() {
                    _selectedContent = selectedContent?.plainText;
                  });
                },
                child: const Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text('Woolha'),
                    Text('dot'),
                    Text('com'),
                  ],
                ),
              ),
              const SizedBox(height: 50),
              Text('Selected content: ${_selectedContent ?? '-'}')
            ],
          ),
        ),
      );
    }
  }

Summary

Flutter's SelectionArea widget can be used if you want to allow the users to perform text selections on a widget subtree. With this widget, you don't have to make each widget selectable such as by using the SelectableText. Just put the SelectionArea widget as the ancestor of all selectable widgets.