之前封装了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插件开发的方方面面,实战讲解多个案例(包含本插件开发过程)
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!