# demo_scan **Repository Path**: FlutterProjects/demo_scan ## Basic Information - **Project Name**: demo_scan - **Description**: Flutter扫描二维码插件,iOS以及Android - **Primary Language**: Dart - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-04-14 - **Last Updated**: 2023-05-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Flutter扫描二维码插件,iOS以及Android [pub地址](https://pub.dev/packages/demo_scan) ## 效果如图 ![Untitled](assets/Untitled.gif) ## 使用方法 ``` dependencies: flutter: sdk: flutter demo_scan: ``` ## Example example/lib/main.dart ``` import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter/services.dart'; import 'package:demo_scan/demo_scan.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { String _platformVersion = 'Unknown'; final _demoScanPlugin = DemoScan(); @override void initState() { super.initState(); initPlatformState(); } // Platform messages are asynchronous, so we initialize in an async method. Future initPlatformState() async { String platformVersion; // Platform messages may fail, so we use a try/catch PlatformException. // We also handle the message potentially returning null. try { platformVersion = await _demoScanPlugin.getPlatformVersion() ?? 'Unknown platform version'; } on PlatformException { platformVersion = 'Failed to get platform version.'; } // If the widget was removed from the tree while the asynchronous platform // message was in flight, we want to discard the reply rather than calling // setState to update our non-existent appearance. if (!mounted) return; setState(() { _platformVersion = platformVersion; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Plugin example app'), ), body: Center( child: Stack( children: [ Text('Running on: $_platformVersion\n'), ], ) ), floatingActionButton: FloatingActionButton( child: Text( "扫码", style: TextStyle( color: Colors.black ), ), backgroundColor: Colors.white, onPressed: () { if (defaultTargetPlatform == TargetPlatform.android) { scan(); } else if (defaultTargetPlatform == TargetPlatform.iOS) { scan(); } else { print("Platform is not yet supported by this plugin"); } }, ), ), ); } Future scan() async { print("扫码开始"); try { String barcode = await DemoScan.scan(); print("扫码结果: ${barcode}"); DemoScan.dismiss(); setState(() { print("扫码结束"); }); } on PlatformException catch (e) { setState(() { print("3333"); print(e); }); } on FormatException { setState(() { print("4444"); print("-----"); }); } catch (e) { setState(() { print("5555"); print(e); }); } } } ``` *** # Flutter plugin 插件制作 ## 制作一个二维码扫码插件 # 目录 * 一、插件介绍 * 二、Flutter部分 * 三、iOS实现 * 四、Android实现 ## 一、插件介绍 `Flutter`中通过`MethodChannel`和原生平台做交互。如图所示: ![1.png](assets/1.png.webp) ### 1、创建插件 **过程依次如下图** ![2](assets/2.png) ![3](assets/3.png) ![4.pic](assets/4.pic.jpg) ### 2、插件目录 ![5.pic](assets/5.pic.jpg) ![6.png](assets/6.png.webp) * `Android` 就是我们开发安卓部分的位置 * `iOS` 就是我们开发 `iOS` 的位置 * `lib` 是与 `Android` 、`iOS` 联调的位置。也可以理解为`Flutter` 实现的位置 * `example` 是测试的位置,当我们写完插件 可以直接运行 插件,`example` 可以理解为一个`Flutter`项目,只不过这个项目只给你写的插件服务 ## 二、Flutter部分 添加`原生`、`Flutter`交互渠道。 ![7](assets/7.jpg) ![8.pic](assets/8.pic.jpg) ![9.pic](assets/9.pic.jpg) ## 三、iOS实现 ![10.pic](assets/10.pic.jpg) ![11.pic](assets/11.pic.jpg) ![12.pic](assets/12.pic.jpg) `pod install`,然后`DemoScanPlugin`写实现代码 本文采用的语言是`Swift`。 找到`Swift`项目名`Plugin.swift`这个文件,该文件就是插件的实现文件。 在`register`方法里,我们注册了一个通道(已经默认注册了),通道名默认就是项目名,该名字在通信里必须是`唯一`的,可以修改,一旦修改,需要把`dart`和`android`里的名字也一并修改。 在`handle`方法里,实现`Flutter`调用原生的`API`,其中`call.method`就是方法名,`call.arguments`就是`Flutter`传递过来的参数。使用`result(返回值)`可以把结果返回给`Flutter`。 当找不到方法名时,可以返回`FlutterMethodNotImplemented`给`Flutter`表示该方法还没实现,以此来做版本兼容。 ![13.pic](assets/13.pic.jpg) 然后Flutter可实现调用 ## 四、Android实现 ![14.pic](assets/14.pic.jpg) ![15.pic](assets/15.pic.jpg) ![16.pic](assets/16.pic.jpg) 该文件就是插件的实现文件。也可以在`DemoScanPlugin`实现。 ![17](assets/17.png) 注意安卓需要`MainActivity`里面初始化一下,如:需要在`flutter_demo`里面用到。 ![18.pic](assets/18.pic.jpg) `AndroidManifest.xml` 里面需要注册跳转的安卓页面 ![19.pic](assets/19.pic.jpg) Flutter调用同iOS一样 **具体细节见代码**