QR codes are ubiquitous in the modern world, serving as a quick and convenient way to share information, whether it’s website URLs, contact details, or payment requests. Flutter, Google’s UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase, makes it straightforward to integrate QR code generation and scanning capabilities into your apps.
Why Use QR Codes in Flutter?
QR codes offer numerous advantages for Flutter application development:
- Seamless Information Sharing: Enables users to quickly share data without manual input.
- Mobile Payments: Facilitates secure and contactless payment options.
- Authentication: Simplifies user authentication processes.
- Inventory Management: Streamlines inventory tracking and management systems.
- Marketing Campaigns: Allows for engaging and interactive marketing experiences.
Prerequisites
Before you begin, ensure that you have the following installed:
- Flutter SDK: Set up Flutter on your development machine.
- Dart SDK: Dart comes bundled with the Flutter SDK.
- Android Studio or VS Code: Code editors for Flutter development.
Setting Up a Flutter Project
Create a new Flutter project by running:
flutter create qr_code_app
Navigate into the project directory:
cd qr_code_app
Generating QR Codes in Flutter
To generate QR codes in Flutter, we’ll use the qr_flutter
package, which provides a simple way to create QR code images.
Step 1: Add the qr_flutter
Dependency
Open the pubspec.yaml
file and add the qr_flutter
package to your dependencies:
dependencies:
flutter:
sdk: flutter
qr_flutter: ^4.1.0
Run flutter pub get
in the terminal to install the package.
Step 2: Implement QR Code Generation
Now, let’s create a widget that generates a QR code from a given string.
import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
class QRCodeGenerator extends StatelessWidget {
final String data;
const QRCodeGenerator({Key? key, required this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: QrImageView(
data: data,
version: QrVersions.auto,
size: 200.0,
gapless: false,
errorStateBuilder: (cxt, err) {
return const Center(
child: Text(
"Uh oh! Something went wrong...",
textAlign: TextAlign.center,
),
);
},
),
);
}
}
In this example:
QrImageView
is the widget provided byqr_flutter
for rendering QR codes.data
is the string you want to encode into the QR code.version
determines the QR code version (QrVersions.auto
lets the library choose).size
defines the dimensions of the QR code image.gapless
controls whether to add a gap around the QR code’s data modules.errorStateBuilder
is a callback for handling errors during QR code generation.
Step 3: Use the QRCodeGenerator
Widget
Integrate the QRCodeGenerator
into your main app:
import 'package:flutter/material.dart';
import 'qr_code_generator.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QR Code Generator',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('QR Code Generator'),
),
body: const QRCodeGenerator(data: 'https://www.example.com'),
),
);
}
}
Replace 'https://www.example.com'
with the data you want to encode.
Scanning QR Codes in Flutter
To scan QR codes, we’ll use the qr_code_scanner
package, which provides a view for scanning QR codes using the device’s camera.
Step 1: Add the qr_code_scanner
Dependency
Open the pubspec.yaml
file and add the qr_code_scanner
package to your dependencies:
dependencies:
flutter:
sdk: flutter
qr_code_scanner: ^1.0.1
Run flutter pub get
in the terminal to install the package.
Step 2: Add Camera Permissions
For Android, add the camera permission to android/app/src/main/AndroidManifest.xml
:
For iOS, add the camera usage description to ios/Runner/Info.plist
:
NSCameraUsageDescription
This app needs camera access to scan QR codes.
Step 3: Implement QR Code Scanning
Create a widget that scans QR codes using the device’s camera.
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QRCodeScanner extends StatefulWidget {
const QRCodeScanner({Key? key}) : super(key: key);
@override
State createState() => _QRCodeScannerState();
}
class _QRCodeScannerState extends State {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (result != null)
Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
else
const Text('Scan a code'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.toggleFlash();
setState(() {});
},
child: FutureBuilder(
future: controller?.getFlashStatus(),
builder: (context, snapshot) {
return Text('Flash: ${snapshot.data}');
},
)),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.flipCamera();
setState(() {});
},
child: FutureBuilder(
future: controller?.getCameraInfo(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Text(
'Camera facing ${describeEnum(snapshot.data!)}');
} else {
return const Text('loading');
}
},
)),
)
],
),
],
),
),
)
],
),
);
}
Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the layout accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to detect orientation changes.
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
});
});
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')),
);
}
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
In this example:
QRView
is the widget provided byqr_code_scanner
for displaying the camera view and scanning QR codes._onQRViewCreated
is called when the QR view is created, allowing you to interact with theQRViewController
.scannedDataStream
listens for scanned QR code data.- Camera permissions are requested and handled.
Step 4: Use the QRCodeScanner
Widget
Integrate the QRCodeScanner
into your main app:
import 'package:flutter/material.dart';
import 'qr_code_scanner.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QR Code Scanner',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('QR Code Scanner'),
),
body: const QRCodeScanner(),
),
);
}
}
Testing Your Flutter QR Code App
Run the Flutter app on an emulator or a physical device to test QR code generation and scanning:
flutter run
Make sure to grant camera permissions when prompted.
Conclusion
Integrating QR code generation and scanning capabilities into your Flutter apps is straightforward using packages like qr_flutter
and qr_code_scanner
. These features can enhance user experience, streamline processes, and provide innovative solutions for information sharing and more. By following this guide, you can easily implement QR code functionality in your Flutter projects, making them more versatile and user-friendly.