动画二维码扫描器

一个二维码扫描器 Widget,目前仅在 Android 上可用(欢迎对 iOS 实现进行 Pull Request),通过原生嵌入平台视图在 Flutter 中实现。

这项工作基于 Julius Canute 的 qr_code_scanner Flutter 包。

在检测到二维码之前,屏幕中央会显示一个装饰性方框,该方框会动画到二维码的位置以突出显示它。当在突出显示动画的开始和/或结束检测到二维码时,解码后的文本将传递给回调函数。

通过 zxing 的 Detector 和 Perspective Transform,这些已被移植到 Flutter,再次计算出 Flutter 显示屏上检测到的代码的位置。

控制器还可以存储文本,并提供基本控件,例如打开闪光灯和重新启动扫描。

也可以对定位框进行样式设置。

演示

Animated-QR-Code-Scanner

安装

将此包用作库

1. 依赖它

将此添加到您的 package 的 pubspec.yaml 文件中

dependencies:
  animated_qr_code_scanner:
    git:
      url: https://github.com/kiatuki/animated_qr_code_scanner.git
      ref: v0.1.2

2. 安装它

您可以从命令行安装包

使用 Flutter

$ flutter pub get

或者,您的编辑器可能支持 flutter pub get。请查看您编辑器的文档以了解更多信息。

3. 导入它

现在,在您的 Dart 代码中,您可以使用

import 'package:animated_qr_code_scanner/animated_qr_code_scanner.dart';

示例

检测到二维码时,在控制台打印解码后的文本,并开始动画定位框以突出显示检测到的二维码。
然后,在突出显示二维码后,显示一个对话框,让用户选择是重新扫描还是确认代码。
如果用户确认代码,则会显示一个带有代码的页面。

class TestPage extends StatelessWidget {
  final AnimatedQRViewController controller = AnimatedQRViewController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
            child: AnimatedQRView(
              squareColor: Colors.green.withOpacity(0.25),
              animationDuration: const Duration(milliseconds: 400),
              onScanBeforeAnimation: (String str) {
                print('Callback at the beginning of animation: $str');
              },
              onScan: (String str) async {
                await showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text("Callback at the end of animation: $str"),
                    actions: [
                      FlatButton(
                        child: Text('OK'),
                        onPressed: () {
                          Navigator.of(context).pop();
                          Navigator.of(context).pop();
                          Navigator.of(context).push(
                            MaterialPageRoute(
                              builder: (context) => Scaffold(
                                body: Align(
                                  alignment: Alignment.center,
                                  child: Text("$str"),
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                      FlatButton(
                        child: Text('Rescan'),
                        onPressed: () {
                          Navigator.of(context).pop();
                          controller.resumeCamera();
                        },
                      ),
                    ],
                  ),
                );
              },
              controller: controller,
            ),
          ),
          Container(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                FlatButton(
                  color: Colors.blue,
                  child: Text('Flash'),
                  onPressed: () {
                    controller.toggleFlash();
                  },
                ),
                const SizedBox(width: 10),
                FlatButton(
                  color: Colors.blue,
                  child: Text('Flip'),
                  onPressed: () {
                    controller.flipCamera();
                  },
                ),
                const SizedBox(width: 10),
                FlatButton(
                  color: Colors.blue,
                  child: Text('Resume'),
                  onPressed: () {
                    controller.resumeCamera();
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

手电筒

默认情况下,闪光灯是关闭的。

controller.toggleFlash();

恢复/暂停

暂停相机流和扫描器。

controller.pause();

恢复相机流和扫描器。

controller.resume();

设置定位方框的样式

更改定位方框的内部和边框的颜色,以及动画持续时间

AnimatedQRView(
    squareColor: Colors.teal.withOpacity(0.25),
    squareBorderColor: Colors.cyan,
    animationDuration: const Duration(milliseconds: 400),
    ...
),

待办事项

即使意图已更改,QR Detector 仍然可以检测到条形码

在原生层而不是 Flutter 层计算 QR 角点

iOS 实现

前置摄像头的动画不正确

GitHub

https://github.com/kiatuki/animated_qr_code_scanner