Reputation: 359
When I try to call my widget it's showing an error on the controller that _controller is not initialized I try to set it in initstate.
class CameraApp extends StatefulWidget {
final dynamic loadingWidget;
CameraApp(this.loadingWidget);
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> with WidgetsBindingObserver {
late List<CameraDescription> _cameras;
late CameraController _controller;
int _selected = 0;
@override
void initState() {
CameraController _controller;
super.initState();
setupCamera();
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance!.addObserver(this);
_controller.dispose();
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
if (_controller == null || !_controller.value.isInitialized) {
return;
}
if (state == AppLifecycleState.inactive) {
_controller.dispose();
} else if (state == AppLifecycleState.resumed) {
setupCamera();
}
}
@override
Widget build(BuildContext context) {
if (_controller == null) {
if (widget.loadingWidget != null) {
return widget.loadingWidget;
} else {
return Container(
color: Colors.black,
);
}
} else {
return CameraPreview(_controller);
}
}
Future<void> setupCamera() async {
await [
Permission.camera,
].request();
_cameras = await availableCameras();
var controller = await selectCamera();
setState(() => _controller = controller);
}
selectCamera() async {
var controller =
CameraController(_cameras[_selected], ResolutionPreset.max);
await controller.initialize();
return controller;
}
toggleCamera() async {
int newSelected = (_selected + 1) % _cameras.length;
_selected = newSelected;
var controller = await selectCamera();
setState(() => _controller = controller);
}
}
I am showing this camera on some widgets but don't figure out how to solve this issue. Maybe because of late it's causing an issue. Showing every time when its load i also try to add contoller.initialize(); in initstate but not working
Upvotes: 1
Views: 3680
Reputation: 1
CameraController _controller = null;
It can't take null value.
Upvotes: 0
Reputation: 5020
LateError means a variable declared using the late
keyword has not been initialized by the time you try to use it, as a general rule, I try to never use the late
keyword unless there is no better way to achieve what I want because it tends to cause hard to find errors.
So you have two late
variables, _controller
and _cameras
.
both initialize on the setupCamera
method, which is asynchronous and gets called on initState
, but the problem I believe is that initState
does not wait for them to finish initializing before running build
, where you try to read _controller
and, because you have yet to assign it, you get a LateError.
If my assertion is correct, it should be a relatively simple fix:
from:
late List<CameraDescription> _cameras;
late CameraController _controller;
to:
List<CameraDescription> _cameras = []; // could also be null I guess.
CameraController _controller = null;
You already have null checks everywhere in case _controller
is null, I believe you should take advantage of that so that if build
runs before _controller
has a value assigned, you get the loading widget.
Upvotes: 1