flutterdartflutter-web

Accessing text selected in SelectionArea Flutter


I am using SelectionArea on top of a ListView with Texts.

Is there a way to access the selected text in the SelectionArea Class?

Looking for a callback method like onSelectionChanged from the SelectableText Class.

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SelectionArea(
        child: ListView.separated(
          itemBuilder: (context, index) => Text(
            List.generate(index + 1, (index) => 'Lorem Ipsum').join(' '),
          ),
          separatorBuilder: (_, __) => const SizedBox(height: 20),
          itemCount: 50,
        ),
      ),
    );
  }
}


Solution

  • You can use onSelectionChanged, which was added to SelectionArea widget with Flutter 3.7.0 (you can find it in Release Notes), and released around Jan 24, 2023.

    It's a ValueChanged<SelectedContent?>?, and you can access the selected text via SelectedContent.plainText.

    Example:

    class HomePage extends StatefulWidget {
      const HomePage({super.key});
    
      @override
      State<StatefulWidget> createState() => HomePageState();
    }
    
    class HomePageState extends State<HomePage> {
      String selectedText = "";
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SelectionArea(
            onSelectionChanged: (selectedContent) {
              setState(() {
                selectedText = selectedContent?.plainText ?? "";
              });
            },
            child: Stack(
              children: [
                ListView.separated(
                  itemBuilder: (context, index) => Text(
                    List.generate(index + 1, (index) => 'Lorem Ipsum').join(' '),
                  ),
                  separatorBuilder: (_, __) => const SizedBox(height: 20),
                  itemCount: 50,
                ),
                Positioned(
                  top: 10,
                  right: 10,
                  child: Container(
                    width: 300,
                    height: 300,
                    decoration: BoxDecoration(
                      color: Colors.white.withAlpha(150),
                      border: BoxBorder.all(color: Colors.grey, width: 2.0),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: SingleChildScrollView(
                        child: Text(
                          "Selected text (${selectedText.length} chars):\n"
                          "$selectedText",
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    Demo of the code snippet above, accessing the selected text and displaying it in another widget