0

我正在制作条形码扫描功能。相机进给正在设置_currentImage

// CameraView.dart

  CameraImage _currentImage;
  CameraImage takePhoto() => _currentImage;

  void imageStream(CameraImage image) async {
    print("_currentImage is set with " + image.toString()); // keeps saying it sets 'currentImage'
    this._currentImage = image;
  }

后来我takePhoto从按钮按下处理程序调用并调用'setState'为空......

  void pressedShowBarcodeOnScreenButton() async {
    var image = this.cameraView.takePhoto();
    if (image == null) {
      print(// occurs after having called empty 'setState' every time button is pressed
          "image was null, maybe it is not possible to take images this fast!");
      return;
    }

    var barcode =
        await VisionService.getInstance() // is not producing any errors
            .analyzeBarcode(ImageUtils.toAbstractImage(image));

    if (Utils.isNullOrEmpty(barcode)) {
      return;
    }

    print("got barcode: " + barcode); // prints all barcodes ok, but stops doing so when calling 'setState'

    setState(() {
      // Makes it so that 'currentImage' is null at all times, despite continuously set by imageStream given from log
      //this.scannedBarcodes = [...this.scannedBarcodes, barcode]; // my intention eventual to update a list
    });
  }

我怀疑这可能是由于一些潜在的飞镖行为,或者有某种错误?为什么setState呼叫阻止我访问_currentImage- 或为什么被阻止设置imageStream()

4

1 回答 1

0

CameraView包含流的CameraController,是显示条形码的页面的一部分。于是SetState(){}触发了CameraView的重构,控制器无法重构。可能旧流正在生成日志并且具有误导性。

它有助于CameraController在这种情况下提取,并将其作为单例访问,在CameraViewController我制作的里面:

//...
    static CameraController _cameraController;
    static Future<CameraController> getCameraControllerInstance() async {
    if (_cameraController == null) {
      var cameras = await availableCameras();
      if (cameras?.length == 0) {
        print("the device did not have a camera");
        return null;
      }
      _cameraController = CameraController(cameras[0], ResolutionPreset.max);
      await _cameraController.initialize();
      _cameraController.startImageStream(updateCurrentImage);
    }

    return _cameraController;
  }

FutureBuilder像这样使用它,在CameraView

FutureBuilder futureBuilder() => FutureBuilder<CameraController>(
      future: CameraViewController.getCameraControllerInstance(), // <--!!!
      builder:
          (BuildContext context, AsyncSnapshot<CameraController> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return LoadingPage();
        }

        return content(snapshot.data);
      });

我很想在任何时候都拥有一个 CameraView 实例(?),因为它在更新列表时看起来会出现故障 - 但我认为这将是反模式,因为 Widget 应该自己重新渲染(不可变):

有条码列表的页面内容:

Widget content() {
    return Container(
        child: (Column(children: [
      cameraView, // camera view part of page and recontructed on 'scannedProducts' state change
      header(),
      scanButton(),
      Column(
        children: this.scannedProducts(), /// list
      )
    ])));
  }
于 2021-09-03T10:08:51.333 回答