blog-teaser

How to replace Flutter Scanbot with barKoder into your mobile app

The objective of this tutorial is to walk you through the process of setting up a Flutter project and implementing an Android barcode scanner using flutter_zxing.The objective of this tutorial is to walk you through the process of setting up a Flutter project and implementing an Android barcode scanner using flutter_zxing.The objective of this tutorial is to walk you through the process of setting up a Flutter project and implementing an Android barcode scanner using flutter_scanbot and barkoder_flutter.

Flutter Development Setup

Essential Tools

  • IDE: Android Studio or Visual Studio Code
    • Android Studio is recommended for its robust Android development support
  • Testing Environment: Android device or emulator
    • Physical Android device or
    • Android emulator configured in your IDE

Flutter SDK Installation

  1. Visit the Flutter installation guide
  2. Select your operating system
  3. Choose Android as the development platform
  4. Download and unzip the Flutter SDK
  5. For Windows users: Update the Windows Path Variable

Android Development Environment Setup

  1. Follow the Flutter guide for Android setup
  2. Set up based on your experience level (new or existing Android Studio user)
  3. Accept Flutter Android licenses
  4. Verify your development setup

Verification Process
Run the following command in your terminal or command prompt:

flutter doctor

This command will check your environment and display a report of the status of your Flutter installation. Address any issues it identifies to ensure a smooth development experience.

Additional Considerations

IDE Configuration

  • Install the Flutter and Dart plugins in your chosen IDE
  • Configure the Flutter SDK path in your IDE settings

Emulator Setup (Optional)
If using an emulator:

  1. Open Android Studio
  2. Navigate to Tools > AVD Manager
  3. Create and configure a virtual device

Version Control
Consider setting up version control for your project:

  • Initialize a Git repository
  • Create a .gitignore file to exclude unnecessary files

By following these steps, you'll have a robust Flutter development environment ready for building Android applications.

 

I am going to demonstrate how to replace the Scanbit plugin with the barKoder SDK, in order to build a Flutter barcode scanner that uses the barKoder SDK.

An implementation of the barKoder SDK for building a Flutter barcode scanner

 

This is a guide for the barKoder Flutter Plugin. Follow the simple steps below to use the barkoder_flutter package in your Flutter project:

1. Prepare the environment  

Install Flutter SDK and setup your environment

2. Add your new barkoder flutter package 

In your pubspec.yaml file, you will find the Scanbot Flutter Barcode Scanner package added. You must replace that package with barkoder_flutterIn your pubspec.yaml file, you will find the Scanbot Flutter Barcode Scanner package added. Please replace that package with barkoder_flutter
dependencies:
  flutter:
    sdk: flutter
 barcode_scanner: ^5.1.0

After you remove the Scanbot plugin please  add the barkoder_flutter package to your project, 

dependencies:
    flutter:
      sdk: flutter
   barkoder_flutter: <package version>

If you prefer to use a local package, download the package from the barKoder Portal and set the package path in your project's dependencies:

dependencies:
      flutter:
        sdk: flutter
        barkoder_flutter:
        path: <package local path>

3. Install dependencies 

Run flutter pub get command in terminal to install the specified dependencies in your project

flutter pub get

4. Import package 

Import the barkoder_flutter package in your project with:

import 'package:barkoder_flutter/barkoder_flutter.dart';

5. Initializing the SDK and BarkoderView 

Look at the Scanbot ;  main.dart

import 'package:flutter/material.dart';
import 'package:barcode_scanner/scanbot_barcode_sdk_v2.dart';
const BARCODE_SDK_LICENSE_KEY = "";
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    _initScanbotSdk();
  }
  Future<void> _initScanbotSdk() async {
    var config = ScanbotSdkConfig(
      licenseKey: BARCODE_SDK_LICENSE_KEY,
      loggingEnabled: true,
    );
    try {
      await ScanbotBarcodeSdk.initScanbotSdk(config);
      print('Scanbot SDK initialized successfully');
    } catch (e) {
      print('Error initializing Scanbot SDK: $e');
    }
  }
  
  @override
  Widget build(BuildContext context) {
  ...
}

At this point the barkoder_flutter package is installed and imported in your project. Next step is to add the BarkoderView in your layout and set the licenseKey parameter and onBarkoderViewCreated callback.

There is a key in Scanbot const BARCODE_SDK_LICENSE_KEY = "" that needs to be replaced with the current barKoder license key in the licenseKey: 'KEY'.There is a key in Scanbot const BARCODE_SDK_LICENSE_KEY = ""; that needs to be replaced with the current barKoder license key in thelicenseKey: 'KEY',

@override
  Widget build(BuildContext context) {
    return Scaffold(
      ...,
      body: BarkoderView(
                licenseKey: 'KEY',
                onBarkoderViewCreated: _onBarkoderViewCreated),
      ...
    );

The license key is a string that consists of alphanumerical characters. See section Section 8 to learn how to get a valid license.

6. Ready to Scan Event 

This ScanEvent Scanbot looks exactly like the one below for scanning some barcodes, but you will need to replace the code below with the code provided by us.

Scanbot Scan Event void _startBarcodeScanning() async {

void _startBarcodeScanning() async {
  try {
    // Create the default configuration object.
    var configuration = BarcodeScannerConfiguration();
    // Initialize the use case for single scanning.
    var scanningMode = SingleScanningMode();
    // Enable and configure the confirmation sheet.
    scanningMode.confirmationSheetEnabled = true;
    scanningMode.sheetColor = ScanbotColor("#FFFFFF");
    // Hide/unhide the barcode image.
    scanningMode.barcodeImageVisible = true;
    // Configure the barcode title of the confirmation sheet.
    scanningMode.barcodeTitle.visible = true;
    scanningMode.barcodeTitle.color = ScanbotColor("#000000");
    // Configure the barcode subtitle of the confirmation sheet.
    scanningMode.barcodeSubtitle.visible = true;
    scanningMode.barcodeSubtitle.color = ScanbotColor("#000000");
    // Configure the cancel button of the confirmation sheet.
    scanningMode.cancelButton.text = "Close";
    scanningMode.cancelButton.foreground.color = ScanbotColor("#C8193C");
    scanningMode.cancelButton.background.fillColor = ScanbotColor("#00000000");
    // Configure the submit button of the confirmation sheet.
    scanningMode.submitButton.text = "Submit";
    scanningMode.submitButton.foreground.color = ScanbotColor("#FFFFFF");
    scanningMode.submitButton.background.fillColor = ScanbotColor("#C8193C");
    // Configure other parameters, pertaining to single-scanning mode as needed.
    configuration.useCase = scanningMode;
    // Set an array of accepted barcode types.
    // configuration.recognizerConfiguration.barcodeFormats = [
    //   scanbotV2.BarcodeFormat.AZTEC,
    //   scanbotV2.BarcodeFormat.PDF_417,
    //   scanbotV2.BarcodeFormat.QR_CODE,
    //   scanbotV2.BarcodeFormat.MICRO_QR_CODE,
    //   scanbotV2.BarcodeFormat.MICRO_PDF_417,
    //   scanbotV2.BarcodeFormat.ROYAL_MAIL,
    ///  .....
    // ];
    // Configure other parameters as needed.
  
    var result = await ScanbotBarcodeSdk.startBarcodeScanner(configuration);
    if(result.operationResult == OperationResult.SUCCESS)
    {
      // TODO: present barcode result as needed
      print(result.value?.items.first.type?.name);
    }
  } catch (e) {
    print('Error: $e');
  }
}

Inside _onBarkoderViewCreated callback function the SDK is fully initialized and ready for configuration or to start the scanning process

void _onBarkoderViewCreated(barkoder) {
  _barkoder = barkoder;
  _barkoder.setBarcodeTypeEnabled(BarcodeType.qr, true);
  _barkoder.setRegionOfInterestVisible(true);
  ...
}
void _scanPressed() {
  _barkoder.startScanning((result) {
    // The result from successful scan is received here
  });
}

For the complete usage of the barkoder_flutter plugin please check our sample.

7. Camera permissions 

Our SDK requires camera permission to be granted in order to use scanning features. For Android, the permission is set in the manifest from the plugin. For iOS you need to specify camera permission in Info.plist file inside your project

Add camera permissions to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />

And in ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
 <string>Camera permission</string>

8. Licensing 

The SDK will scan barcodes even without a valid license; however all results will be randomly masked with (*) Asterisk characters. By using our software you are agreeing to our End User License Agreement. To obtain a valid license, one should create an account here and either get a trial license (to test the software out) or procure a production license that can be used within a live app.

9. Example example/lib/main.dart

Scanbot main.dart  looks something like this:

import 'package:flutter/material.dart';
import 'package:barcode_scanner/scanbot_barcode_sdk_v2.dart';
const BARCODE_SDK_LICENSE_KEY = "";
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    _initScanbotSdk();
  }
  Future<void> _initScanbotSdk() async {
    var config = ScanbotSdkConfig(
      licenseKey: BARCODE_SDK_LICENSE_KEY,
      loggingEnabled: true,
    );
    try {
      await ScanbotBarcodeSdk.initScanbotSdk(config);
      print('Scanbot SDK initialized successfully');
    } catch (e) {
      print('Error initializing Scanbot SDK: $e');
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Barcode Scanner'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _startBarcodeScanning,
              style: ElevatedButton.styleFrom(
                padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
                textStyle: const TextStyle(fontSize: 18),
              ),
              child: const Text("Start single-barcode scanning"),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _startBarcodeMultiScanning,
              style: ElevatedButton.styleFrom(
                padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
                textStyle: const TextStyle(fontSize: 18),
              ),
              child: const Text("Start multi-barcode scanning"),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _startAROverlay,
              style: ElevatedButton.styleFrom(
                padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
                textStyle: const TextStyle(fontSize: 18),
              ),
              child: const Text("Start the AR overlay"),
            ),
          ],
        ),
      ),
    );
  }
  void _startBarcodeScanning() async {
    try {
      // Create the default configuration object.
      var configuration = BarcodeScannerConfiguration();
      // Initialize the use case for single scanning.
      var scanningMode = SingleScanningMode();
      // Enable and configure the confirmation sheet.
      scanningMode.confirmationSheetEnabled = true;
      scanningMode.sheetColor = ScanbotColor("#FFFFFF");
      // Hide/unhide the barcode image.
      scanningMode.barcodeImageVisible = true;
      // Configure the barcode title of the confirmation sheet.
      scanningMode.barcodeTitle.visible = true;
      scanningMode.barcodeTitle.color = ScanbotColor("#000000");
      // Configure the barcode subtitle of the confirmation sheet.
      scanningMode.barcodeSubtitle.visible = true;
      scanningMode.barcodeSubtitle.color = ScanbotColor("#000000");
      // Configure the cancel button of the confirmation sheet.
      scanningMode.cancelButton.text = "Close";
      scanningMode.cancelButton.foreground.color = ScanbotColor("#C8193C");
      scanningMode.cancelButton.background.fillColor = ScanbotColor("#00000000");
      // Configure the submit button of the confirmation sheet.
      scanningMode.submitButton.text = "Submit";
      scanningMode.submitButton.foreground.color = ScanbotColor("#FFFFFF");
      scanningMode.submitButton.background.fillColor = ScanbotColor("#C8193C");
      // Configure other parameters, pertaining to single-scanning mode as needed.
      configuration.useCase = scanningMode;
      // Set an array of accepted barcode types.
      // configuration.recognizerConfiguration.barcodeFormats = [
      //   scanbotV2.BarcodeFormat.AZTEC,
      //   scanbotV2.BarcodeFormat.PDF_417,
      //   scanbotV2.BarcodeFormat.QR_CODE,
      //   scanbotV2.BarcodeFormat.MICRO_QR_CODE,
      //   scanbotV2.BarcodeFormat.MICRO_PDF_417,
      //   scanbotV2.BarcodeFormat.ROYAL_MAIL,
      ///  .....
      // ];
      // Configure other parameters as needed.
    
      var result = await ScanbotBarcodeSdk.startBarcodeScanner(configuration);
      if(result.operationResult == OperationResult.SUCCESS)
      {
        // TODO: present barcode result as needed
        print(result.value?.items.first.type?.name);
      }
    } catch (e) {
      print('Error: $e');
    }
  }
  void _startBarcodeMultiScanning() async {
    try {
      // Create the default configuration object.
      var configuration = BarcodeScannerConfiguration();
      // Initialize the use case for multiple scanning.
      var scanningMode = MultipleScanningMode();
      // Set the counting mode.
      scanningMode.mode = MultipleBarcodesScanningMode.COUNTING;
      // Set the sheet mode for the barcodes preview.
      scanningMode.sheet.mode = SheetMode.COLLAPSED_SHEET;
      // Set the height for the collapsed sheet.
      scanningMode.sheet.collapsedVisibleHeight = CollapsedVisibleHeight.LARGE;
      // Enable manual count change.
      scanningMode.sheetContent.manualCountChangeEnabled = true;
      // Set the delay before same barcode counting repeat.
      scanningMode.countingRepeatDelay = 1000;
      // Configure the submit button.
      scanningMode.sheetContent.submitButton.text = "Submit";
      scanningMode.sheetContent.submitButton.foreground.color =
          ScanbotColor("#000000");
      // Configure other parameters, pertaining to multiple-scanning mode as needed.
      configuration.useCase = scanningMode;
      // Set an array of accepted barcode types.
      // configuration.recognizerConfiguration.barcodeFormats = [
      //   BarcodeFormat.AZTEC,
      //   BarcodeFormat.PDF_417,
      //   BarcodeFormat.QR_CODE,
      //   BarcodeFormat.MICRO_QR_CODE,
      //   BarcodeFormat.MICRO_PDF_417,
      //   BarcodeFormat.ROYAL_MAIL,
      ///  .....
      // ];
      // Configure other parameters as needed.
    
      var result = await ScanbotBarcodeSdk.startBarcodeScanner(configuration);
      if(result.operationResult == OperationResult.SUCCESS)
      {
        // TODO: present barcode result as needed
        print(result.value?.items.first.type?.name);
      }
    } catch (e) {
      print('Error: $e');
    }
  }
  void _startAROverlay() async {
    try {
     // Create the default configuration object.
      var configuration = new BarcodeScannerConfiguration();
      // Configure the usecase.
      var usecase = new MultipleScanningMode();
      usecase.mode = MultipleBarcodesScanningMode.UNIQUE;
      usecase.sheet.mode = SheetMode.COLLAPSED_SHEET;
      usecase.sheet.collapsedVisibleHeight = CollapsedVisibleHeight.SMALL;
      // Configure AR Overlay.
      usecase.arOverlay.visible = true;
      usecase.arOverlay.automaticSelectionEnabled = false;
      // Set the configured usecase.
      configuration.useCase = usecase;
      // Set an array of accepted barcode types.
      // configuration.recognizerConfiguration.barcodeFormats = [
      //   BarcodeFormat.AZTEC,
      //   BarcodeFormat.PDF_417,
      //   BarcodeFormat.QR_CODE,
      //   BarcodeFormat.MICRO_QR_CODE,
      //   BarcodeFormat.MICRO_PDF_417,
      //   BarcodeFormat.ROYAL_MAIL,
      ///  .....
      // ];
      var result = await ScanbotBarcodeSdk.startBarcodeScanner(configuration);
      if (result.operationResult == OperationResult.SUCCESS) {
        // TODO: present barcode result as needed
        print(result.value?.items.first.type?.name);
      }
    } catch (e) {
      print('Error: $e');
    }
  }
}

Your new barKoder Flutter final main.dart should look something like this:

import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:barkoder_flutter/barkoder_flutter.dart';
import 'package:image_picker/image_picker.dart';
void main() {
  runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
  const MyApp({super.key});
  @override
  State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  late Barkoder _barkoder;
  bool _isScanningActive = false;
  String _barkoderVersion = '';
  List<DecoderResult> _decoderResults = [];
  List<Uint8List?> _resultThumbnailImages = [];
  Uint8List? _resultImage;
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }
  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
      // _barkoder.stopScanning();
      // _updateState(null, false);
    }
  }
  void _onBarkoderViewCreated(barkoder) async {
    _barkoder = barkoder;
    String barkoderVersion = await _barkoder.getVersion;
    _setActiveBarcodeTypes();
    _setBarkoderSettings();
    // _barkoder.configureBarkoder(BarkoderConfig(
    //   imageResultEnabled: true,
    //   decoder: DekoderConfig(qr: BarcodeConfig(enabled: true)),
    // ));
    if (!mounted) return;
    setState(() {
      _barkoderVersion = barkoderVersion;
    });
  }
  void _setActiveBarcodeTypes() {
    _barkoder.setBarcodeTypeEnabled(BarcodeType.qr, true);
    _barkoder.setBarcodeTypeEnabled(BarcodeType.ean13, true);
    _barkoder.setBarcodeTypeEnabled(BarcodeType.upcA, true);
    _barkoder.setBarcodeTypeEnabled(BarcodeType.code128, true);
  }
  void _setBarkoderSettings() {
    _barkoder.setImageResultEnabled(true);
    _barkoder.setLocationInImageResultEnabled(true);
    _barkoder.setMaximumResultsCount(200);
    _barkoder.setRegionOfInterestVisible(true);
    _barkoder.setPinchToZoomEnabled(true);
    _barkoder.setBarcodeThumbnailOnResultEnabled(true);
    _barkoder.setRegionOfInterest(5, 5, 90, 90);
    // When using image scan it is recommended to use rigorous decoding speed
    // _barkoder.setDecodingSpeed(DecodingSpeed.rigorous);
  }
  void _updateState(BarkoderResult? barkoderResult, bool scanningIsActive) {
    if (!mounted) return;
    setState(() {
      _isScanningActive = scanningIsActive;
      if (barkoderResult != null) {
        _decoderResults.clear();
        _resultThumbnailImages.clear();
        _resultImage?.clear();
        _decoderResults.addAll(barkoderResult.decoderResults);
        if (barkoderResult.resultThumbnails != null) {
          _resultThumbnailImages.addAll(barkoderResult.resultThumbnails!);
        }
        if (barkoderResult.resultImage != null) {
          _resultImage = barkoderResult.resultImage!;
        }
      } else {
        // Clear all values if no result
        _decoderResults.clear();
        _resultThumbnailImages.clear();
        _resultImage = null;
      }
    });
  }
  void _scanPressed() {
    if (_isScanningActive) {
      _barkoder.stopScanning();
    } else {
      _barkoder.startScanning((result) {
        _updateState(result, false);
      });
    }
    _updateState(null, !_isScanningActive);
  }
  void _scanImage() async {
    final ImagePicker _picker = ImagePicker();
    final XFile? pickedFile =
        await _picker.pickImage(source: ImageSource.gallery);
    _barkoder.stopScanning();
    if (pickedFile != null) {
      final bytes = await pickedFile.readAsBytes();
      String base64Image = base64Encode(bytes);
      _barkoder.scanImage((result) {
        if (result.decoderResults.isEmpty) {
          // Only show dialog if no results were found
          _showNoResultsDialog();
        }
        _updateState(result, false);
      }, base64Image);
    } else {
      _updateState(null, true);
    }
    _updateState(null, !_isScanningActive);
  }
  void _showNoResultsDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("No barcodes or MRZ detected :("),
          content: const Text(
              "Please ensure the image you've selected contains at least one barcode, or choose a different image.nAlso, verify that the barcode type you're trying to scan is enabled"),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text("OK"),
            ),
          ],
        );
      },
    );
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFF5F5F5),
      appBar: AppBar(
        backgroundColor: const Color(0xFFFF0022),
        title: Text('Barkoder Sample (v$_barkoderVersion)'),
      ),
      body: Stack(
        children: [
          Column(
            children: [
              Expanded(
                child: Stack(
                  children: <Widget>[
                    // Camera preview
                    BarkoderView(
                      licenseKey: '',
                      onBarkoderViewCreated: _onBarkoderViewCreated,
                    ),
                    // Placeholder Text
                    if (!_isScanningActive && _resultImage == null)
                      const Align(
                        alignment: Alignment.center,
                        child: Text(
                          'Press the button to start scanning',
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.grey, fontSize: 20),
                        ),
                      ),
                    // Display scanned image on top of preview
                    if (_resultImage != null)
                      Align(
                        alignment: Alignment.center,
                        child: Image.memory(
                          _resultImage!,
                          fit: BoxFit.contain,
                          width: MediaQuery.of(context).size.width,
                          height: MediaQuery.of(context).size.height,
                        ),
                      ),
                  ],
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: _decoderResults.isNotEmpty
                      ? _decoderResults.length + 1
                      : 0,
                  itemBuilder: (context, index) {
                    if (index == 0) {
                      return Card(
                        margin: const EdgeInsets.all(10.0),
                        color: Colors.white,
                        child: Padding(
                          padding: const EdgeInsets.all(10.0),
                          child: Center(
                            child: Text(
                              '${_decoderResults.length} result${_decoderResults.length > 1 ? 's' : ''} found',
                              style: const TextStyle(
                                fontSize: 16,
                                fontWeight: FontWeight.bold,
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ),
                      );
                    }
                    final result = _decoderResults[index - 1];
                    final thumbnailImage = _resultThumbnailImages.isNotEmpty &&
                            index - 1 < _resultThumbnailImages.length
                        ? _resultThumbnailImages[index - 1]
                        : null;
                    return Card(
                      margin: const EdgeInsets.all(10.0),
                      color: Colors.white,
                      child: Padding(
                        padding: const EdgeInsets.all(10.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            const Text(
                              "Result",
                              style: TextStyle(
                                  color: Colors.red,
                                  fontWeight: FontWeight.bold),
                            ),
                            Text(result.textualData),
                            const Divider(),
                            const Text(
                              "Type",
                              style: TextStyle(
                                  color: Colors.red,
                                  fontWeight: FontWeight.bold),
                            ),
                            Text(result.barcodeTypeName),
                            if (result.extra != null &&
                                result.extra!.isNotEmpty) ...[
                              const Divider(),
                              const Text(
                                "Extras",
                                style: TextStyle(
                                    color: Colors.red,
                                    fontWeight: FontWeight.bold),
                              ),
                              Text(result.extra?.toString() ?? ''),
                            ],
                            if (thumbnailImage != null) ...[
                              const Divider(),
                              const Text(
                                "Thumbnail",
                                style: TextStyle(
                                    color: Colors.red,
                                    fontWeight: FontWeight.bold),
                              ),
                              Image.memory(
                                thumbnailImage,
                                fit: BoxFit.contain,
                                width: 100,
                                height: 100,
                              ),
                            ],
                            if (result.mrzImages != null &&
                                result.mrzImages!.isNotEmpty) ...[
                              const Divider(),
                              const Text(
                                "MRZ Images",
                                style: TextStyle(
                                    color: Colors.red,
                                    fontWeight: FontWeight.bold),
                              ),
                              Column(
                                children: result.mrzImages!.map((mrzImage) {
                                  return Padding(
                                    padding: const EdgeInsets.only(top: 8.0),
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          mrzImage.name,
                                          style: const TextStyle(
                                              fontWeight: FontWeight.bold,
                                              color: Colors.black),
                                        ),
                                        Image.memory(
                                          mrzImage.value,
                                          fit: BoxFit.contain,
                                          width: 200,
                                          height: 200,
                                        ),
                                      ],
                                    ),
                                  );
                                }).toList(),
                              ),
                            ],
                          ],
                        ),
                      ),
                    );
                  },
                ),
              ),
            ],
          ),
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        mainAxisSize: MainAxisSize.min,
        children: [
          FloatingActionButton(
            onPressed: _scanImage,
            child: const Icon(Icons.photo),
            backgroundColor: Colors.white,
          ),
          const SizedBox(width: 16),
          FloatingActionButton(
            tooltip: _isScanningActive ? 'Stop scan' : 'Start scan',
            onPressed: _scanPressed,
            backgroundColor: _isScanningActive ? Colors.red : Colors.white,
            child: const Icon(Icons.qr_code_scanner),
          ),
        ],
      ),
    );
  }
}

 

 

 

Latest Barcode Scanner SDK Articles,
Tutorials, and News