Unknown error in custom actions

Hi, I wanted to implement this qr view as I want a constant qr page. (flutterflow's qr quits when a qr is scanned, I don't want that)

I just changed it a bit as I want to trigger an action when a qr is scanned.

Here is the code (I know it's a lot, but I will answer any question about it.)

// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!

import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class QRViewExample extends StatefulWidget {
  const QRViewExample(
      {Key? key, this.width, this.height, required this.onScanned, this.result})
      : super(key: key);

  final double? width;
  final double? height;
  final Future<String> Function() onScanned;
  final String? result;

  @override
  State<StatefulWidget> createState() => _QRViewExampleState();
}

class _QRViewExampleState extends State<QRViewExample> {
  QRViewController? controller;
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');

  String? result; // Add a non-final result variable

  @override
  void initState() {
    super.initState();
    result = widget.result; // Initialize result with the widget's result
  }

  @override
  void reassemble() {
    super.reassemble();
    if (Platform.isAndroid) {
      controller!.pauseCamera();
    }
    controller!.resumeCamera();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Expanded(flex: 4, child: _buildQrView(context)),
          Expanded(
            flex: 1,
            child: FittedBox(
              fit: BoxFit.contain,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  _buildResultText(),
                  _buildFlashButton(),
                  _buildCameraFlipButton(),
                  _buildCameraControlButtons(),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }

  Widget _buildResultText() {
    return result != null
        ? Text('Barcode Type: Data: ${result}')
        : const Text('Scan a code');
  }

  Widget _buildFlashButton() {
    return 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}');
          },
        ),
      ),
    );
  }

  Widget _buildCameraFlipButton() {
    return 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 _buildCameraControlButtons() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Container(
          margin: const EdgeInsets.all(8),
          child: ElevatedButton(
            onPressed: () async {
              await controller?.pauseCamera();
            },
            child: const Text('pause', style: TextStyle(fontSize: 20)),
          ),
        ),
        Container(
          margin: const EdgeInsets.all(8),
          child: ElevatedButton(
            onPressed: () async {
              await controller?.resumeCamera();
            },
            child: const Text('resume', style: TextStyle(fontSize: 20)),
          ),
        ),
      ],
    );
  }

  Widget _buildQrView(BuildContext context) {
    var scanArea = (MediaQuery.of(context).size.width < 400 ||
            MediaQuery.of(context).size.height < 400)
        ? 150.0
        : 300.0;

    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) async {
      FFAppState().scanData = scanData.code!;
      await widget.onScanned(); // Assuming this is asynchronous
      setState(() {
        result = scanData.code;
      });
    });
  }

  void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
    log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
    if (!p) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('no Permission')),
      );
    }
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }
}

// Set your widget name, define your parameter, and then add the
// boilerplate code using the button on the right!

1
2 replies