Flutter 最佳扫码插件——自定义视图
之前封装了Flutter扫码插件后,许多人希望能提供自定义视图的支持,于是将flutter_scankit 升级到v1.2。关于该插件的介绍以及基础用法,请查看上一篇《Flutter 最佳扫码插件》自定义视图使用插件库提供的ScanKitWidget作为扫码控件,建议用Stack布局组合其他控件实现自定义视图。在创建ScanKitWidget时,必须实现其回调函数callback,该回调返回一个S
之前封装了Flutter扫码插件后,许多人希望能提供自定义视图的支持,于是将flutter_scankit 升级到v1.2。关于该插件的介绍以及基础用法,请查看上一篇《Flutter 最佳扫码插件》
自定义视图
使用插件库提供的ScanKitWidget作为扫码控件,建议用Stack布局组合其他控件实现自定义视图。
在创建ScanKitWidget时,必须实现其回调函数callback,该回调返回一个ScanKitController,用于调用与扫码相关的功能。
ScanKitWidget(
callback: (controller) {
_controller = controller;
},
)
创建ScanKitWidget时,还有一些属性可以设置:
-
boundingBox:设置识码区域的位置大小 -
format:指定扫码的类型,不传默认为全部类型,与 startScan方法scanTypes参数相同,参考startScan -
continuouslyScan:设置是否为连续扫码模式
以上属性的解释,可参考HUAWEI ScanKit 的 官方文档。
ScanKitController中包含如下方法:
getLightStatus():当前闪光灯是否开启switchLight():切换闪光灯(on/off)pickPhoto():拉起图库,从图片识别二维码dispose()pauseContinuouslyScan()resumeContinuouslyScan()
需要注意的是,pauseContinuouslyScan()和resumeContinuouslyScan()仅Android平台支持,关于这两个方法的说明,请查看 这里
另外,ScanKitController的onLightVisible属性也是仅Android平台支持,它是判断环境光亮明暗的监听,返回值为布尔类型,true表示场景昏暗;false表示场景明亮。开发者可通过该监听实现自动开启闪光灯功能。
获取识码结果
监听ScanKitController的onResult属性
ScanKitWidget(
callback: (controller) {
_controller = controller;
controller.onResult.listen((result) {
debugPrint("scanning result:$result");
});
},
完整示例
实现自定义视图:
class CustomizedView extends StatefulWidget {
@override
_CustomizedViewState createState() => _CustomizedViewState();
}
const boxSize = 200.0;
class _CustomizedViewState extends State<CustomizedView> {
late ScanKitController _controller;
final screenWidth = window.physicalSize.width;
final screenHeight = window.physicalSize.height;
@override
void dispose(){
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var pixelSize = boxSize * window.devicePixelRatio;
var left = screenWidth/2 - pixelSize/2;
var top = screenHeight/2 - pixelSize/2;
var right = screenWidth/2 + pixelSize/2;
var bottom = screenHeight/2 + pixelSize/2;
var rect = Rect.fromLTRB(left, top, right, bottom);
return Scaffold(
body: SafeArea(
child: Stack(
children: [
ScanKitWidget(
callback: (controller) {
_controller = controller;
controller.onResult.listen((result) {
debugPrint("scanning result:$result");
Navigator.of(context).pop(result);
});
},
continuouslyScan: false,
boundingBox: rect),
Align(
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
size: 28,
)),
IconButton(
onPressed: () {
_controller.switchLight();
},
icon: Icon(
Icons.lightbulb_outline_rounded,
color: Colors.white,
size: 28,
)),
IconButton(
onPressed: () {
_controller.pickPhoto();
},
icon: Icon(
Icons.picture_in_picture_rounded,
color: Colors.white,
size: 28,
))
],
),
),
Align(
alignment: Alignment.center,
child: Container(
width: boxSize,
height: boxSize,
decoration: BoxDecoration(
border: Border(
left: BorderSide(color: Colors.orangeAccent, width: 2),
right: BorderSide(color: Colors.orangeAccent, width: 2),
top: BorderSide(color: Colors.orangeAccent, width: 2),
bottom: BorderSide(color: Colors.orangeAccent, width: 2)),
),
),
)
],
),
),
);
}
}
拉起自定义视图:
Future<void> newPage(BuildContext context) async {
var code = await Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) {
return CustomizedView();
}
));
setState(() {
this.code = code ?? "";
});
}
完整代码参见 Example
视频课程
希望系统学习Flutter应用开发,可以参加我的网校中的 《Flutter 全栈式开发指南》课程。
想学习Flutter插件开发,在我的网校中查看《Flutter全栈式开发-高级篇》课程,从零开始插件开发,包含Android/iOS原生基础,全网独家深入解析关于Flutter插件开发的方方面面,实战讲解多个案例(包含本插件开发过程)

欢迎关注公众号:编程之路从0到1

更多推荐


所有评论(0)