QR and Barcodes are very famous technology that widely used around us. In these codes, you can store information like text, URL, image, and a few other information.
Nowadays, most of the e-commerce companies using this technology to track their product purchase with the help of QR code and Barcode unique IDs. This QR and barcodes can only read by a physical scanner device because these are not humanly readable.
We can read QR codes with the help of appropriate software installed on the smartphone camera and other QR supported devices. The encoded action will be performed automatically if the code is readable.
In this post, our aim to create a QR/Barcode detection and generate QR code in a Flutter Application. By using this application, you can scan any QR/Barcode and encode any message in the QR code. The final output of the application will look like below:
2. Now, add the plugin qr_flutter and flutter_qr_bar_scanner as a dependency in the pubspec.yaml file. Once you do that, you need to run flutter packages.
3. We have created a class theme.dart that we'll use to design home screen background. So, put the following file in the project directory.
4. Now, edit main.dart file as we have used qr_barcode_screen.dart to display QR/Barcode scanner and generator option on one screen:
5. After that create qr_barcode_screen.dart class, where we going to create a widget for QR/Barcode scanner and generate QR code. As we planned to display both features on a single screen. We going to use PageView to displays two widgets on a single screen by providing a slide feature as you can see above video:
the _buildScan method return widget that shows scanner widget and a Text widget to display scanned value. Here, we have used QRBarScannerCamera widget to create a scanner window of Codes. It has qrCodeCallback method that provides scanned value of codes.
the _buildGen return a QR code generate widget. It shows generated QR code and Textfield to enter text for generate encoded QR code.
the _buildGenButton refresh QR code widget with latest QR code values:
the _buildMenuBar display scan and generate slidable buttons.
here, we have complete code snippet of QR/Barcode Screen:
You can use source code of this example from below the Github link and you can see the working demo by using Android APK:
If you have followed the post carefully, you can see the app running very smoothly as shown in the above video and you able to scan and generate QR code. But if you are facing any problem or you have any quires, please feel free to ask it from comment section.
Nowadays, most of the e-commerce companies using this technology to track their product purchase with the help of QR code and Barcode unique IDs. This QR and barcodes can only read by a physical scanner device because these are not humanly readable.
What is QR Code?
It is a 2-dimensional bar code that stands for Quick Response Code. The QR code can encode over 4000 characters, including punctuation marks and special characters that can be entered in one code by black squares over white background. The encoded content of a QR code cannot be change once generated. The QR codes may be used to display text, contact to the address book and web site URL as we have encoded www.developerlibs.com in the following QR code:www.developerlibs.com |
What is Barcode?
The Barcode is a square or rectangular image that contains vertical lines with varying widths. It contains full information about products like serial numbers, product numbers, etc. A bar code has five parts: a quiet zone, a start character, data characters, a stop character, and another quiet zone. They are used in retail stores as part of the product purchase process, in warehouses to track inventories, and among many other uses. The smartphones or barcode scanners can read this encoded information of the barcode. Here, we have an example of Barcode that contains www.developerlibs.com text encoded in the following barcode:In this post, our aim to create a QR/Barcode detection and generate QR code in a Flutter Application. By using this application, you can scan any QR/Barcode and encode any message in the QR code. The final output of the application will look like below:
Creating a new Project
1. Create a new project from File ⇒ New Flutter Project with your development IDE.2. Now, add the plugin qr_flutter and flutter_qr_bar_scanner as a dependency in the pubspec.yaml file. Once you do that, you need to run flutter packages.
3. We have created a class theme.dart that we'll use to design home screen background. So, put the following file in the project directory.
import 'dart:ui'; import 'package:flutter/cupertino.dart'; class Colors { const Colors(); static const Color loginGradientStart = const Color(0xFF02BB9F); static const Color loginGradientEnd = const Color(0xFF167F67); static const primaryGradient = const LinearGradient( colors: const [loginGradientStart, loginGradientEnd], stops: const [0.0, 1.0], begin: Alignment.topCenter, end: Alignment.bottomCenter, ); }
4. Now, edit main.dart file as we have used qr_barcode_screen.dart to display QR/Barcode scanner and generator option on one screen:
import 'package:flutter/material.dart'; import 'package:flutterqrbarcode/qr_barcode_screen.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'QR Generator-Scanner', home: QRBarcodeScreen(), ); } }
5. After that create qr_barcode_screen.dart class, where we going to create a widget for QR/Barcode scanner and generate QR code. As we planned to display both features on a single screen. We going to use PageView to displays two widgets on a single screen by providing a slide feature as you can see above video:
Expanded( flex: 2, child: PageView( controller: _pageController, onPageChanged: (i) { if (i == 0) { setState(() { right = Colors.white; left = Colors.black; }); } else if (i == 1) { setState(() { right = Colors.black; left = Colors.white; }); } }, children: <Widget>[ _buildScan(context), _buildGen(context), ], ), ),
the _buildScan method return widget that shows scanner widget and a Text widget to display scanned value. Here, we have used QRBarScannerCamera widget to create a scanner window of Codes. It has qrCodeCallback method that provides scanned value of codes.
Widget _buildScan(BuildContext context) { return Center( child: Card( elevation: 2.0, color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), child: Container( padding: const EdgeInsets.all(10.0), width: 300, height: 500, child: Column( children: <Widget>[ Container( height: 300, width: 280, margin: const EdgeInsets.only(bottom: 10), child: QRBarScannerCamera( onError: (context, error) => Text( error.toString(), style: TextStyle(color: Colors.red), ), qrCodeCallback: (code) { _qrCallback(code); }, ), ), Text( _qrInfo, style: TextStyle(color: Colors.black26), ), ], ), )), ); }
the _buildGen return a QR code generate widget. It shows generated QR code and Textfield to enter text for generate encoded QR code.
Widget _buildGen(BuildContext context) { final bodyHeight = MediaQuery.of(context).size.height - MediaQuery.of(context).viewInsets.bottom; return Center( child: Card( elevation: 2.0, color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), child: Container( width: 300, height: 500, padding: const EdgeInsets.all(10.0), child: Column( children: <Widget>[ Container( height: 300, width: 280, child: RepaintBoundary( key: globalKey, child: QrImage(data: _dataString, size: 0.5 * bodyHeight), ), ), Padding( padding: EdgeInsets.only( top: 20.0, bottom: 20.0, left: 25.0, right: 25.0), child: TextFormField( focusNode: mFocusNodeQrValue, controller: _textController, textCapitalization: TextCapitalization.words, style: TextStyle(fontSize: 16.0, color: Colors.black), decoration: InputDecoration( hintText: "Enter Text", hintStyle: TextStyle(fontSize: 16.0), ), ), ), _buildGenButton(context), ], ), ), ), ); }
the _buildGenButton refresh QR code widget with latest QR code values:
Widget _buildGenButton(BuildContext context) { return GestureDetector( onTap: () { setState(() { _dataString = _textController.text; }); }, child: Container( width: 150.0, height: 50.0, decoration: BoxDecoration( color: Theme.Colors.loginGradientEnd, borderRadius: BorderRadius.all(Radius.circular(25.0)), ), child: Center( child: Icon( Icons.refresh, color: Colors.white, ), ), )); }
the _buildMenuBar display scan and generate slidable buttons.
Widget _buildMenuBar(BuildContext context) { return Container( width: 300.0, height: 50.0, decoration: BoxDecoration( color: Color(0x552B2B2B), borderRadius: BorderRadius.all(Radius.circular(25.0)), ), child: CustomPaint( painter: TabIndicationPainter(pageController: _pageController), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Expanded( child: FlatButton( splashColor: Colors.transparent, highlightColor: Colors.transparent, onPressed: _onScanButtonPress, child: Text( "Sacn", style: TextStyle( color: left, fontSize: 16.0, ), ), ), ), Expanded( child: FlatButton( splashColor: Colors.transparent, highlightColor: Colors.transparent, onPressed: _onGenerateButtonPress, child: Text( "Generate", style: TextStyle( color: right, fontSize: 16.0, ), ), ), ), ], ), ), ); }
here, we have complete code snippet of QR/Barcode Screen:
import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_qr_bar_scanner/qr_bar_scanner_camera.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'bubble_indication_painter.dart'; import 'theme.dart' as Theme; class QRBarcodeScreen extends StatefulWidget { QRBarcodeScreen({Key key}) : super(key: key); @override _QrBarcodeState createState() => new _QrBarcodeState(); } class _QrBarcodeState extends State<QRBarcodeScreen> with SingleTickerProviderStateMixin { final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final FocusNode mFocusNodeQrValue = FocusNode(); TextEditingController qrController = new TextEditingController(); PageController _pageController; Color left = Colors.black; Color right = Colors.white; GlobalKey globalKey = new GlobalKey(); String _dataString = "www.developerlibs.com"; final TextEditingController _textController = TextEditingController(); String _qrInfo = 'Scan a QR/Bar code'; @override Widget build(BuildContext context) { return new Scaffold( key: _scaffoldKey, body: SingleChildScrollView( child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, decoration: new BoxDecoration( gradient: new LinearGradient( colors: [ Theme.Colors.loginGradientStart, Theme.Colors.loginGradientEnd ], begin: const FractionalOffset(0.0, 0.0), end: const FractionalOffset(1.0, 1.0), stops: [0.0, 1.0], tileMode: TileMode.clamp), ), child: Column( mainAxisSize: MainAxisSize.max, children: <Widget>[ Expanded( flex: 2, child: PageView( controller: _pageController, onPageChanged: (i) { if (i == 0) { setState(() { right = Colors.white; left = Colors.black; }); } else if (i == 1) { setState(() { right = Colors.black; left = Colors.white; }); } }, children: <Widget>[ _buildScan(context), _buildGen(context), ], ), ), Padding( padding: EdgeInsets.only(top: 1.0, bottom: 50), child: _buildMenuBar(context), ), ], ), ), ), ); } @override void dispose() { mFocusNodeQrValue.dispose(); _pageController?.dispose(); super.dispose(); } @override void initState() { super.initState(); _pageController = PageController(); } Widget _buildMenuBar(BuildContext context) { return Container( width: 300.0, height: 50.0, decoration: BoxDecoration( color: Color(0x552B2B2B), borderRadius: BorderRadius.all(Radius.circular(25.0)), ), child: CustomPaint( painter: TabIndicationPainter(pageController: _pageController), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Expanded( child: FlatButton( splashColor: Colors.transparent, highlightColor: Colors.transparent, onPressed: _onScanButtonPress, child: Text( "Sacn", style: TextStyle( color: left, fontSize: 16.0, ), ), ), ), //Container(height: 33.0, width: 1.0, color: Colors.white), Expanded( child: FlatButton( splashColor: Colors.transparent, highlightColor: Colors.transparent, onPressed: _onGenerateButtonPress, child: Text( "Generate", style: TextStyle( color: right, fontSize: 16.0, ), ), ), ), ], ), ), ); } Widget _buildGenButton(BuildContext context) { return GestureDetector( onTap: () { setState(() { _dataString = _textController.text; }); }, child: Container( width: 150.0, height: 50.0, decoration: BoxDecoration( color: Theme.Colors.loginGradientEnd, borderRadius: BorderRadius.all(Radius.circular(25.0)), ), child: Center( child: Icon( Icons.refresh, color: Colors.white, ), ), )); } _qrCallback(String code) { setState(() { _qrInfo = code; }); } Widget _buildScan(BuildContext context) { return Center( child: Card( elevation: 2.0, color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), child: Container( padding: const EdgeInsets.all(10.0), width: 300, height: 500, child: Column( children: <Widget>[ Container( height: 300, width: 280, margin: const EdgeInsets.only(bottom: 10), child: QRBarScannerCamera( onError: (context, error) => Text( error.toString(), style: TextStyle(color: Colors.red), ), qrCodeCallback: (code) { _qrCallback(code); }, ), ), Text( _qrInfo, style: TextStyle(color: Colors.black26), ), ], ), )), ); } Widget _buildGen(BuildContext context) { final bodyHeight = MediaQuery.of(context).size.height - MediaQuery.of(context).viewInsets.bottom; return Center( child: Card( elevation: 2.0, color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), child: Container( width: 300, height: 500, padding: const EdgeInsets.all(10.0), child: Column( children: <Widget>[ Container( height: 300, width: 280, child: RepaintBoundary( key: globalKey, child: QrImage(data: _dataString, size: 0.5 * bodyHeight), ), ), Padding( padding: EdgeInsets.only( top: 20.0, bottom: 20.0, left: 25.0, right: 25.0), child: TextFormField( focusNode: mFocusNodeQrValue, controller: _textController, textCapitalization: TextCapitalization.words, style: TextStyle(fontSize: 16.0, color: Colors.black), decoration: InputDecoration( hintText: "Enter Text", hintStyle: TextStyle(fontSize: 16.0), ), ), ), _buildGenButton(context), ], ), ), ), ); } void _onScanButtonPress() { _pageController.animateToPage(0, duration: Duration(milliseconds: 500), curve: Curves.decelerate); } void _onGenerateButtonPress() { _pageController?.animateToPage(1, duration: Duration(milliseconds: 500), curve: Curves.decelerate); } }
You can use source code of this example from below the Github link and you can see the working demo by using Android APK:
If you have followed the post carefully, you can see the app running very smoothly as shown in the above video and you able to scan and generate QR code. But if you are facing any problem or you have any quires, please feel free to ask it from comment section.