Flutter开发 - 二维码扫描
项目开发中, 经常会用到二维码扫描, 而一个二维码扫描页面最常见的功能包括两点:
- 二维码扫描
- 扫描动画
二维码扫描
Flutter中, 二维码扫描需要与原生交互. 因此需要做对应的插件开发.
下面简单介绍下, 之前开发的一个二维码扫描插件.
qrcode
该插件, 在iOS中使用的AVCaptureSession, Android中使用的是zxing.
pub: pub.flutter-io.cn/packages/qr…
github: github.com/SiriDx/qrco…
添加依赖
在pubspec.yaml添加
dependencies:
qrcode: ^1.0.2
安装
执行命令
flutter pub get
Import
import 'package:qrcode/qrcode.dart';
基本使用
- QRCaptureView
// 扫描捕捉视图, 传入QRCaptureController对象
QRCaptureView(controller: _captureController)
- QRCaptureController
// 获取扫描结果
_captureController.onCapture((data) {
print('onCapture----$data');
});
// 恢复与暂停扫描
_captureController.resume();
_captureController.pause();
// 设置手电筒模式
_captureController.torchMode = CaptureTorchMode.off;
_captureController.torchMode = CaptureTorchMode.on;
示例
class _MyAppState extends State<MyApp> {
QRCaptureController _captureController = QRCaptureController();
bool _isTorchOn = false;
@override
void initState() {
super.initState();
_captureController.onCapture((data) {
print('onCapture----$data');
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Stack(
alignment: Alignment.center,
children: <Widget>[
QRCaptureView(controller: _captureController),
Align(
alignment: Alignment.bottomCenter,
child: _buildToolBar(),
)
],
),
),
);
}
Widget _buildToolBar() {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
onPressed: () {
_captureController.pause();
},
child: Text('pause'),
),
FlatButton(
onPressed: () {
if (_isTorchOn) {
_captureController.torchMode = CaptureTorchMode.off;
} else {
_captureController.torchMode = CaptureTorchMode.on;
}
_isTorchOn = !_isTorchOn;
},
child: Text('torch'),
),
FlatButton(
onPressed: () {
_captureController.resume();
},
child: Text('resume'),
),
],
);
}
}
集成
iOS中, 需要在info.plist中添加以下内容, 并在<string></string>
中填写请求相机权限的描述
<key>NSCameraUsageDescription</key>
<string>Camera permission is required for qrcode scanning.</string>
<key>io.flutter.embedded_views_preview</key>
<true/>
扫描动画
使用Tween实现来回扫描的动画
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
Animation<Alignment> _animation;
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(seconds: 1));
_animation =
AlignmentTween(begin: Alignment.topCenter, end: Alignment.bottomCenter)
.animate(_animationController)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.reverse();
} else if (status == AnimationStatus.dismissed) {
_animationController.forward();
}
});
_animationController.forward();
}
@override
void dispose() {
super.dispose();
_animationController.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Stack(
alignment: Alignment.center,
children: <Widget>[
QRCaptureView(
controller: _captureController,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 56),
child: AspectRatio(
aspectRatio: 264 / 258.0,
child: Stack(
alignment: _animation.value,
children: <Widget>[
Image.asset('images/sao@3x.png'),
Image.asset('images/tiao@3x.png')
],
),
),
),
],
),
),
);
}
}
在qrcode插件的example/lib/main中, 可以查看完整代码