6

Flutter Clipboard 剪贴板操作: 复制到剪贴板 / 从剪贴板中获取

 3 years ago
source link: https://www.bugcatt.com/archives/1766
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

阿航

2020年5月30日

57

Flutter Clipboard 剪贴板操作: 复制到剪贴板 / 从剪贴板中获取

我们在使用Flutter进行开发时, 有时会使用类似”复制本段文字”的功能. 为了提升用户体验, 我们不希望用户长按文字, 再自行复制, 我们希望提供一个按钮直接点击复制, 甚至自动复制! 反之从剪贴板获取也一样.

有图有真相, 不说废话, 直接展示最终效果:

复制到剪贴板

Flutter剪贴板操作-03

从剪贴板获取(粘贴)

Flutter剪贴板操作-04

如果你了解阿航的技术小站, 应该会知悉每篇文章都会提供相当详细且完整的源码.

复制到剪贴板

  1. 生成了运单号, 需要用户进行保存;
  2. 某些微商APP需要复制文案, 发布朋友圈;
  3. 文学类APP中, 发现一段非常好的句子, 想发给好友.

从剪贴板中获取

  1. 直接填入用户复制的短信验证码.
  2. 淘宝分享的东西, 复制后打开淘宝APP.
当然, 以上只是举了几种例子, 还有更多可以提升用户操作体验的实例在此不过多举例了, 直接开始.

初始化Flutter项目

创建Flutter项目, 清理一下./lib/main.dart:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter剪贴板操作',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter剪贴板操作'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

运行下项目, 应该空空如也:

Flutter%E5%89%AA%E8%B4%B4%E6%9D%BF%E6%93%8D%E4%BD%9C-01.png

复制到剪贴板

先来做”复制到剪贴板”的功能.

_MyHomePageState中定义一个实例变量_txtToBeCopied:

// 待复制的文字
String _txtToBeCopied = "";

💡 该变量用于存储待复制的文字

为了更直观的展现, 我们来定义一个函数_chgTxt(), 用于替换待复制的文字, 先导入:

import 'dart:math';

再在_MyHomePageState定义函数:

/// 变更待复制的文字
void _chgTxt() {
  _txtToBeCopied = Random().nextInt(10000).toString();
}

💡 代码解析: 我们使用了dart:math库中的Random对象, 并生成10000以内的随机数. 这样每次调用该函数时, 待复制的文字都会被替换为新的数字!

我们要把待复制的文字显示出来, 替换:

Text(
  'You have pushed the button this many times:',
),
Text(
  '$_counter',
  style: Theme.of(context).textTheme.headline4,
),,
Text(
  '待复制的文字:',
),
Text(
  _txtToBeCopied,
  style: Theme.of(context).textTheme.headline3,
),

💡 我们在第一个Text中给出了文字提示, 在第二个Text中展示了待复制的文字_txtToBeCopied变量值.

import 'package:flutter/services.dart';

紧接着我们来定义一个按钮, 分别用于”生成文字”和”复制”. 在第二个Text下面添加:

Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    RaisedButton(
      onPressed: () => _chgTxt(),
      child: Text("生成文字"),
    ),
    RaisedButton(
      onPressed: () {
        Clipboard.setData(ClipboardData(text: _txtToBeCopied))
            .then((value) => print("已复制!"));
      },
      child: Text("复制"),
    )
  ],
),

💡 代码解析: 这段代码我们添加了两个按钮, 第一个”生成文字”按钮用于调用_chgTxt(), 用于生成随机的数字.
第二个”复制”按钮就是我们的重点, 将生成的文字复制.

代码截图:

运行项目, 如果代码没有问题, 你应该可以成功复制! 效果:

获取剪贴板内容(粘贴)

做完了复制到剪贴板, 我们来做相反的操作, 那就是从剪贴板中获取.

定义一个实例变量_txtToBePaste(在_txtToBeCopied下方), 用于保存粘贴的文字方便后续展示:

// 用于展示粘贴的文字
String _txtToBePaste = "";

在刚才的两个按钮下面(Row下面)添加几个widget:

Text(
  '剪贴板的文字:',
),
Text(
  _txtToBePaste,
  style: Theme.of(context).textTheme.headline3,
),
RaisedButton(
  onPressed: () {
    Clipboard.getData(Clipboard.kTextPlain).then((value) {
      if (value != null) {
        _txtToBePaste = value.text;
        setState(() {});
      }
    });
  },
  child: Text("获取"),
),

💡 代码解析: 我们的重点是在Clipboard.getData()上, 我们通过此函数就可以获取剪贴板的内容. 并通过value.text获取其String类型的值.

再次运行项目, 如果代码没有问题, 应该可以达到我们的效果了!
Flutter%E5%89%AA%E8%B4%B4%E6%9D%BF%E6%93%8D%E4%BD%9C-04.gif

本篇文章的全部源码:

import 'dart:math';

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter剪贴板操作',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter剪贴板操作'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  int _counter = 0;

  // 待复制的文字
  String _txtToBeCopied = "";

  // 保存粘贴的文字
  String _txtToBePaste = "";

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  /// 变更待复制的文字
  void _chgTxt() {
    setState(() {
      _txtToBeCopied = Random().nextInt(10000).toString();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              '待复制的文字:',
            ),
            Text(
              _txtToBeCopied,
              style: Theme.of(context).textTheme.headline3,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                RaisedButton(
                  onPressed: () => _chgTxt(),
                  child: Text("生成文字"),
                ),
                RaisedButton(
                  onPressed: () {
                    Clipboard.setData(ClipboardData(text: _txtToBeCopied))
                        .then((value) => print("已复制!"));
                  },
                  child: Text("复制"),
                )
              ],
            ),
            Text(
              '剪贴板的文字:',
            ),
            Text(
              _txtToBePaste,
              style: Theme.of(context).textTheme.headline3,
            ),
            RaisedButton(
              onPressed: () {
                Clipboard.getData(Clipboard.kTextPlain).then((value) {
                  if (value != null) {
                    _txtToBePaste = value.text;
                    setState(() {});
                  }
                });
              },
              child: Text("获取"),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

复制到剪贴板

Clipboard.setData(ClipboardData(text: "你要复制的文字"))
    .then((value) => print("已复制!"));

这里要注意的是这个是个异步函数, 需要你进行妥善处理.

从剪贴板获取

Clipboard.getData(Clipboard.kTextPlain).then((value) {
  print(value.text);
});

同样是个异步函数, 一定要注意运行顺序的问题哦!

问题&解决方案

问: 在导出为Web项目时, 调用复制功能, 浏览器报错.

答: 一般是浏览器限制的原因, 由Http更换为Https试一下.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK