213

I'm a beginner to Flutter and I just started following their Name Generator app tutorial and made a simple name generating app. I'm wondering if it's possible to add copy to clipboard feature when a user tap on a name? I tried to implement a solution I found on stack but it didn't work. My full code is here. Any advise is appreciated.

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

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Startup Name Generator',
      home: new RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => new RandomWordsState();
}

class RandomWordsState extends State<RandomWords> {
  final List<WordPair> _suggestions = <WordPair>[];
  final Set<WordPair> _saved = new Set<WordPair>();
  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Startup Name Generator'),
        actions: <Widget>[
          new IconButton(icon: const Icon(Icons.list), onPressed: _pushSaved),
        ],
      ),
      body: _buildSuggestions(),
    );
  }

  Widget _buildSuggestions() {
    return new ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemBuilder: (BuildContext _context, int i) {
          if (i.isOdd) {
            return const Divider();
          }
          final int index = i ~/ 2;
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10));
          }
          return _buildRow(_suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    final bool alreadySaved = _saved.contains(pair);

    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: new Icon(
        alreadySaved ? Icons.favorite : Icons.favorite_border,
        color: alreadySaved ? Colors.red : null,
      ),
      onTap: () {
        setState(() {
          if (alreadySaved) {
            _saved.remove(pair);
          } else {
            _saved.add(pair);
          }
        });
      },
    );
  }

  void _pushSaved() {
    Navigator.of(context).push(
      new MaterialPageRoute<void>(
        builder: (BuildContext context) {
          final Iterable<ListTile> tiles = _saved.map(
                (WordPair pair) {
              return new ListTile(
                title: new Text(
                  pair.asPascalCase,
                  style: _biggerFont,
                ),
              );
            },
          );
          final List<Widget> divided = ListTile
              .divideTiles(
            context: context,
            tiles: tiles,
          )
              .toList();
          return new Scaffold(
            appBar: new AppBar(
              title: const Text('Saved Suggestions'),
            ),
            body: new ListView(children: divided),
          );

        },
      ),
    );
  }
}
Gihan
  • 3,144
  • 2
  • 9
  • 36

5 Answers5

550

import:

import 'package:flutter/services.dart';

And then Simply implement this:

onTap: () async {
  await Clipboard.setData(ClipboardData(text: "your text"));
  // copied successfully
},
SwiftiSwift
  • 7,528
  • 9
  • 56
  • 96
Houssem
  • 6,409
  • 3
  • 18
  • 28
79

If you want better solution without any dependency that working async use this:

import 'package:flutter/services.dart';

Clipboard.setData(ClipboardData(text: email)).then((_){
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Email address copied to clipboard")));
});

There was breaking changes that you might find useful in the following link: https://docs.flutter.dev/release/breaking-changes/scaffold-messenger

Vinoth Vino
  • 9,166
  • 3
  • 66
  • 70
Ron Shoshani
  • 913
  • 8
  • 13
  • 9
    Showing snackbar in Scaffold is deprecated, you should use ScaffoldMessenger. ScaffoldMessenger.of(context) .showSnackBar(SnackBar( content: Text("Your text")) ); – ShadeToD May 13 '21 at 07:26
35

You can use this below code without adding any plugins & notify the user:

Notifying user by Scaffold.of(context).showSnackBar(snackBar); is deprecated so use below updated code.

import 'package:flutter/services.dart';

Clipboard.setData(const ClipboardData(text: "Your Copy text")).then((_) {
  ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('Copied to your clipboard !')));
});
Vinoth Vino
  • 9,166
  • 3
  • 66
  • 70
MohanKumar
  • 960
  • 10
  • 26
12

You can use the Flutter clipboard_manager package: Flutter clipboard manager

To install it, follow the instructions on this page, pretty straightforward: Flutter clipboard manager installation process

To use it, import it in the .dart file you're writing and then you can use this: ClipboardManager.copyToClipBoard("your text to copy")

Where "your text to copy" can be substituted by any string you want to copy to the clipboard.

If you want to create a snackbar after copying the text, since it's async you can do:

ClipboardManager.copyToClipBoard("your text to copy").then((result) {
                        final snackBar = SnackBar(
                          content: Text('Copied to Clipboard'),
                          action: SnackBarAction(
                            label: 'Undo',
                            onPressed: () {},
                          ),
                        );
                        Scaffold.of(context).showSnackBar(snackBar);
                      });

Adendum: If you look at the package source code what it basically does is this:

Clipboard.setData(ClipboardData(text: "your text to copy"));

However, I find that the extra bit of syntactic sugar and the advantage of being async makes it a better solution, nothing you can't do with vanilla Flutter, but I find it a bit better.

Yashwardhan Pauranik
  • 5,370
  • 5
  • 42
  • 65
Doodles
  • 313
  • 2
  • 12
  • 36
    Why install a plugin! Other answer is simpler, using `'package:flutter/services.dart'` – Samer Jun 24 '19 at 19:30
  • 6
    There's already a big open issue for this library - https://github.com/anuranBarman/ClipboardManager/issues/13 I am not discouraging the use of this library - but after adding this as a dependency - and building the app in release mode - the following task fails - 'verifyReleaseResources' - it simply means - there's some vulnerable code detected in the library. Flutter has inbuilt clipboard feature - prefer that. – abhijat_saxena Sep 09 '20 at 19:54
  • Agreed, a repeated problem with the Flutter ecosystem of making it so easy to create pub.dev packages is that I see a lot of solutions recommending bad coding practice or an overly complex approach to doing something the Dart and Flutter libraries already do natively. `Clipboard.setData()` is already a Future so you can still use `.then(...)` if you really want to, or just `await` the call. – Jeff Neet Aug 26 '22 at 22:32
2

Now in Flutter 3.3 that global selection is available, flutter provides the ability to select the entire text in web applications with the help of the new wizard called selectable area. As you can see from the image, we are using the select table area visit, and in this wizard, we are able to select any text within the wizard, just like we can do in web applications.

SelectionArea(
        child: Scaffold(
          appBar: AppBar(title: const Text(_title)),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: const <Widget>[
                Text('Row 1'),
                Text('Row 2'),
                Text('Row 3'),
              ],
            ),
          ),
        ),
      )

for demo, checkout here.

Shirsh Shukla
  • 5,491
  • 3
  • 31
  • 44