zp_qr_scanner 1.1.2
zp_qr_scanner: ^1.1.2 copied to clipboard
A high-performance Flutter QR scanner plugin powered by native camera textures on iOS (AVFoundation) and Android (CameraX + ML Kit).
zp_qr_scanner #
A high-performance Flutter QR scanner plugin powered by native camera textures on iOS (AVFoundation) and Android (CameraX + bundled ML Kit), streamed into Flutter via TextureRegistry.
✨ Features #
- 📱 iOS & Android:
AVFoundationon iOS,CameraX+ bundledML Kiton Android (no Google Play Services required). - ⚡ High Performance: Native camera texture streaming directly into Flutter via
Texture(textureId: ...), avoiding expensive platform view and image conversion overhead. - 🎯 Smooth Real-time Tracking: Automatically detects and tracks QR corners with smooth bounding box and scanning animations. The preview freezes on the exact frame the QR was detected in, so the corners always line up.
- 🔦 Torch & Focus Controls: Built-in support for toggling flashlight and manual tap-to-focus.
- 📳 Haptic Feedback: Built-in haptic feedback on successful scans.
- 📱 Low Memory & Battery Efficient: Clean lifecycle management with automatic resume and pause.
🚀 Getting Started #
1. Add dependency #
Add zp_qr_scanner to your pubspec.yaml:
dependencies:
zp_qr_scanner: ^1.1.2
Or install it via CLI:
flutter pub add zp_qr_scanner
2. Platform Setup #
iOS Setup
Add the camera permission description to your ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to scan QR codes and barcodes.</string>
Note: Requires iOS 15.5 or higher.
Android Setup
No extra setup is needed: the plugin declares the CAMERA permission and requests it at runtime when start() is called.
minSdkVersion21 or higher.- Your activity must be a
FlutterActivityorFlutterFragmentActivity(the default for Flutter apps). - The QR model is bundled (ML Kit), so scanning works without Google Play Services; it adds roughly 2–3 MB per ABI to the APK.
App size impact #
Measured with ./.build/analyze-size.sh (Flutter 3.29.0, release build, empty app vs. app using QrScannerView):
| Platform | Added size |
|---|---|
| Android arm64-v8a | ~3.9 MB |
| Android armeabi-v7a | ~3.6 MB |
| iOS arm64 | ~0.2 MB |
On Android most of it is the bundled ML Kit barcode model; iOS uses the system AVFoundation framework.
📖 Usage #
Basic Scanner View #
Use QrScannerView to display a full-featured scanner screen:
import 'package:flutter/material.dart';
import 'package:zp_qr_scanner/zp_qr_scanner.dart';
class ScanPage extends StatelessWidget {
const ScanPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: QrScannerView(
onScanned: (String value) async {
// Handle scan result
await showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Scanned Result'),
content: Text(value),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(),
child: const Text('OK'),
),
],
),
);
// Once the Future finishes, scanner resumes automatically!
},
),
);
}
}
Scan frame position
The idle scan frame is centered by default. Use scanBoxAlignment to move it and scanBoxOffset to fine-tune it in logical pixels:
QrScannerView(
onScanned: _handleScanned,
scanBoxAlignment: const Alignment(0, -0.3), // a bit above center
scanBoxOffset: const Offset(0, 16), // then 16px down
)
The whole camera frame is still scanned, so a QR code outside the frame is detected too.
Low-level API (ZpQrScanner) #
If you want custom UI or manual camera control:
// Start camera session and get texture metadata
final QrTexture texture = await ZpQrScanner.start();
print('Texture ID: ${texture.id}, Size: ${texture.size}');
// Listen to scanned results stream
final subscription = ZpQrScanner.results.listen((QrScanResult result) {
print('Scanned value: ${result.value}');
print('Corners: ${result.corners}');
});
// Toggle torch / flashlight
await ZpQrScanner.setTorch(true);
// Focus at a specific point (normalized 0.0 - 1.0)
await ZpQrScanner.focus(const Offset(0.5, 0.5));
// Pause and resume
await ZpQrScanner.stop();
await ZpQrScanner.resume();
🛠️ Example #
Check out the complete sample project in the example/ directory.
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.