未定义函数 setState

问题描述

我正在尝试在我的移动应用中制作条形码扫描仪。我制作了一个名为barcode_scanner.dart 的文件一个名为barcode_scanner_bloc.dart 的文件。我试图在barcode_scanner_bloc.dart 中编写scan() 方法并从barcode_scanner.dart 调用它。 为此,我这样做了:

import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:Flutter/material.dart';

import 'barcode_scanner_bloc.dart';

class ScanBarcode extends StatefulWidget {
  @override
  _ScanBarcodeState createState() => _ScanBarcodeState();

  static scan() {}
}

class _ScanBarcodeState extends State<ScanBarcode> {
  String barcode = "";
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: new Text('Code Scanner'),centerTitle: true,),body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.stretch,children: <Widget>[
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.0,vertical: 8.0),child: RaisedButton(
                color: Colors.purple,textColor: Colors.white,splashColor: Colors.blueGrey,onpressed: scan,child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
                    Icon(Icons.scanner,size: 40),SizedBox(width: 10),Column(
                      children: <Widget>[
                        Text('Camera Scan'),SizedBox(
                          height: 2,Text('Click here')
                      ],)
                  ],Padding(
              padding: EdgeInsets.symmetric(horizontal: 16,vertical: 8),child: Text(
                barcode,textAlign: TextAlign.center,)
            
          ],);
  }
}

现在我正在尝试添加 scan() 方法,但是当我尝试在另一个文件中执行此操作时,它给出了错误。这是我的代码

import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:Flutter/material.dart';

import 'barcode_scanner.dart';




Future scan() async {
  try {
    String barcode = await ScanBarcode.scan();
    setState(() {
      this.barcode = barcode;
    });
  } on PlatformException catch (e) {
    if (e.code == ScanBarcode.CameraAccessDenied) {
      setState(() {
        this.barcode = 'camera permission not granted';
      });
    } else {
      setState(() {
        this.barcode = 'UnkNown error: $e';
      });
    }
  } on FormatException {
    setState(() {
      this.barcode = 'null (user returned using the back button)';
    });
  } catch (e) {
    setState(() {
      this.barcode = 'UnkNown error: $e';
    });
  }
}

如果有人能帮助我,我会很高兴。

解决方法

您无法从 setState 外部访问 StatefulWidget

尝试在 scan() 类中使用 StatefulWidget 函数

或者尝试让scan()函数返回barcode的值然后调用setState

所以它会像

Future<String> scan() async {
  try {
    String barcode = await ScanBarcode.scan();
    return barcode;
  } on PlatformException catch (e) {
    if (e.code == ScanBarcode.CameraAccessDenied) {
        return 'camera permission not granted';
    } else {
       return 'Unknown error: $e';
    }
  } on FormatException {
    return  'null (user returned using the back button)';
  } catch (e) {
     return  'Unknown error: $e';
  }
}

在你的 ScanBarcode 课上

onPressed: () async {
setState(() {
        this.barcode = await scan();
      });
},
,

我认为您要么需要设置通知和侦听器模式,要么需要使用流控制器设置流。我个人使用 flutter_bloc 包来做到这一点(youtube 上每个都有完整的颤振教程)。使用 flutter_bloc,您可以像这样从您的小部件调用 scan():

bloc.add(ScanEventStart());

基本上,您向 BLoC 发送一个事件,它会将状态返回到您的小部件的 BlocBuilder 小部件。

,

谢谢两位!如果您能回答,我还有一个问题,在这个 if (e.code == ScanBarcode.CameraAccessDenied) 部分中,它给出了“未为 ScanBarcode 类型定义 getter CameraAccessDenied”的错误我应该整合它吗?我是编码和颤振的新手,所以我不知道这些类型的东西。