LateInitializationError: Field 'cameras' has not been initialized.
I'm new to flutter and learn creating a chat app and now I want to enable camera. but im getting above error in my code. how can I solve this. appreciate your help on this.
CameraScreen.dart
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
late List <CameraDescription> cameras;
class CameraScreen extends StatefulWidget {
const CameraScreen({Key? key}) : super(key: key);
@override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
late CameraController _cameraController;
late Future<void> cameraValue;
@override
void initState() {
// TODO: implement initState
super.initState();
_cameraController = CameraController(cameras[0],ResolutionPreset.high);
cameraValue = _cameraController.initialize();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
FutureBuilder(
future: cameraValue,
builder: (context,snapshot) {
if(snapshot.connectionState==ConnectionState.done){
return CameraPreview(_cameraController);
}
else{
return Center(
child: CircularProgressIndicator(),
);
}
}
)
],
),
);
}
}
main.dart
Future <void> main() async{
WidgetsFlutterBinding.ensureInitialized();
cameras =await availableCameras();
runApp(const MyApp());
}
CodePudding user response:
You are not initializing you cameras object in your cameras.dart file, you are doing that on your main file, but those instances are not the same. If you are following the example in https://pub.dev/packages/camera be aware that main and camera widget are on the same file so the instance of cameras is unique.
If you want to have separate files for main and your widget you should pass the camera instance via the constructor. Something like:
Future <void> main() async{
WidgetsFlutterBinding.ensureInitialized();
cameras =await availableCameras();
runApp(const MyApp(cameras: cameras));
}
and your widget should be something like this:
class CameraScreen extends StatefulWidget {
List <CameraDescription> cameras;
const CameraScreen({Key? key, required this.cameras}) : super(key: key);
@override
_CameraScreenState createState() => _CameraScreenState();
}
CodePudding user response:
At the moment of you try to reach out to the cameras, you do not have access to it. You need to wait for the cameras to be loaded and then call the CameraScreen.
I would suggest doing the following:
/// main.dart
Future <void> main() async{
WidgetsFlutterBinding.ensureInitialized();
final cameras =await availableCameras();
runApp(const MyApp(cameras: cameras));
}
/// MyApp.dart
class MyApp extends StatelessWidget {
const MyApp({required this.cameras, Key? key}) : super(key: key);
final List<CameraDescription> cameras;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CameraScreen(cameras: cameras),
),
);
}
}
/// CameraScreen.dart
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
class CameraScreen extends StatefulWidget {
const CameraScreen({required this.cameras, Key? key}) : super(key: key);
final List<CameraDescription> cameras;
@override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
late CameraController _cameraController;
late Future<void> cameraValue;
@override
void initState() {
// TODO: implement initState
super.initState();
_cameraController = CameraController(widget.cameras[0],ResolutionPreset.high);
cameraValue = _cameraController.initialize();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
FutureBuilder(
future: cameraValue,
builder: (context,snapshot) {
if(snapshot.connectionState==ConnectionState.done){
return CameraPreview(_cameraController);
}
else{
return Center(
child: CircularProgressIndicator(),
);
}
}
)
],
),
);
}
}