我正在制作条形码扫描功能。摄像头进给设置为_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
});
}
我怀疑这可能是由于一些底层的dart行为,或者有某种bug?为什么setState
呼叫阻止我访问_currentImage
-或者imageStream()
呼叫阻止我设置
包含具有流的CameraController
的CameraView
是显示条形码的页面的一部分。所以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 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
)
])));
}