大家好,我遇到以下问题,希望有人可以帮助我: 我尝试使用以下代码将相机包含在我的 flutter 应用程序中:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
class Route02 extends StatefulWidget {
@override
CameraState createState() => CameraState();
}
class CameraState extends State<Route02> {
late List<CameraDescription> cameras;
late CameraController _controller;
bool isReady = false;
@override
void initState() {
super.initState();
setupCameras();
}
Future<void> setupCameras() async {
try {
cameras = await availableCameras();
_controller = new CameraController(cameras[0], ResolutionPreset.ultraHigh);
await _controller.initialize();
} on CameraException catch () {
setState(() {
isReady = false;
});
}
setState(() {
isReady = true;
});
}
Widget build(BuildContext context) {
if (!isReady && !_controller.value.isInitialized) {
return Container();
}
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller));
}
}
在应用程序内访问相机部分时,可以看到以下错误,然后相机仍会启动:
LateInitializationError:字段“控制器”尚未初始化。
我已经尝试添加 whenComplete() 方法并使用了 ? 但它也不起作用。
有人有想法吗?
我认为问题在于您正在运行“setupCameras()”,它在“initState()”方法中是异步的,而“initState()”方法不是。试试这个:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
class Route02 extends StatefulWidget {
@override
CameraState createState() => CameraState();
}
class CameraState extends State<Route02> {
late List<CameraDescription> cameras;
late CameraController _controller;
Future<void> setupCameras() async {
try {
cameras = await availableCameras();
_controller = new CameraController(cameras[0], ResolutionPreset.ultraHigh);
await controller.initialize();
}
Widget build(BuildContext context) {
return FutureBuilder(
future: setupCameras(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller)
);
};
);
}
}
我也遇到同样的问题,找不到完美的解决方案。
我认为 FutureBuilder 在这种情况下不起作用。您还需要处理处置。这似乎不是您使用 FutureBuilder 可以做到的。
现实情况是,你可能无法成功初始化CameraController。无论出于何种原因, getCameras 都不会返回任何内容。这意味着您的 CameraController 始终有可能为 null。因此,尝试调整代码以强制其为非空类型是不正确的。
我最终只是将其更改为可空类型,并在必要时进行空检查。在我看来,dart 在零安全性方面已经走得太远了。它只会让事情变得更加复杂。我喜欢 Python 使用 None 处理可为空的方式。
CameraController? _controller;
我看到两个问题:
setupCameras()
确实:
try { // ... } on CameraException catch () { setState(() { isReady = false; }); } setState(() { isReady = true; });
这意味着如果抛出
CameraException
,isReady
将被设置为 false
,但随后立即被设置为 true
。
build
函数的作用是:
if (!isReady && !_controller.value.isInitialized) { return Container(); }
如果
isReady
为 false(我认为 should 表明 _controller
尚未初始化),那么即使 _controller.value.isInitialized
尚未初始化,您还要检查 _controller
。您可能想要 ||
而不是 &&
。
或者,考虑仅将
_controller
设置为空,而不是 late
。如果您需要在访问 isReady
之前检查布尔标志 (_controller
),这并不比使 _controller
可为空并直接检查 _controller != null
更好,这样更直接且更不容易出错。
代码中的错误“LateInitializationError:字段'controller'尚未初始化”与_controller变量未正确初始化有关。看来您正在尝试在 initState 方法中初始化 _controller 之前使用它。您应该仅在初始化后访问 _controller。这是代码的修改版本,以确保正确初始化:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera';
class Route02 extends StatefulWidget {
@override
CameraState createState() => CameraState();
}
class CameraState extends State<Route02> {
late List<CameraDescription> cameras;
late CameraController _controller;
bool isReady = false;
@override
void initState() {
super.initState();
setupCameras();
}
Future<void> setupCameras() async {
try {
cameras = await availableCameras();
_controller = CameraController(cameras[0], ResolutionPreset.ultraHigh);
// Ensure that the widget is mounted before initializing the controller
if (!mounted) {
return;
}
await _controller.initialize();
setState(() {
isReady = true;
});
} on CameraException catch (e) {
print("Error: $e");
setState(() {
isReady = false;
});
}
}
@override
void dispose() {
_controller.dispose(); // Don't forget to dispose of the controller.
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!isReady || !_controller.value.isInitialized) {
return Container();
}
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller),
);
}
}
注意:在初始化之前检查小部件是否仍然挂载 相机控制器以避免错误。还添加了一个 dispose 方法 处理小部件时正确处理相机控制器。