Home > database >  Flutter camera error LateInitializationError: Field 'cameraController' has not been initia
Flutter camera error LateInitializationError: Field 'cameraController' has not been initia

Time:01-31

I'm trying to write a code to use the camera with Flutter, but even by following the steps seen online it cannot initialize cameraController.

Here is my code :

class CameraPage extends StatefulWidget {
  const CameraPage({Key? key}) : super(key: key);

  @override
  State<CameraPage> createState() => _CameraPageState();
}

class _CameraPageState extends State<CameraPage> {

  late List<CameraDescription> cameras;
  late CameraController cameraController;

  @override
  void initState() {
    startCamera();
    super.initState();
  }

  void startCamera() async {
    cameras = await availableCameras();

    cameraController = CameraController(
        cameras[0],
        ResolutionPreset.high
    );

    print(" Camera controller : $cameraController");

    cameraController.initialize().then((value) {
      if(!mounted) {
        return;
      }
      setState(() {}); //To refresh widget

    }).catchError((e) {
      print(e);
    });
  }



  @override
  void dispose() {
    cameraController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    if(cameraController.value.isInitialized) {
      return Scaffold(
        body: Stack(
          children: [
            CameraPreview(cameraController),
          ],
        ),
      );
    } else {
      return SizedBox();
    }
  }
}

The print(" Camera controller : $cameraController"); is working fine and returns me a camera controller, so it might be initialized at some point ?

CodePudding user response:

Your problem is that in the first build your camera controller is not initialized yet, because initialization is in an async method. You can use a Boolean flag to track is initialized, before accessing the late property.

bool _cameraInitialized = false;

void startCamera() async {
    cameras = await availableCameras();

    cameraController = CameraController(cameras[0], ResolutionPreset.high);

    print(" Camera controller : $cameraController");

    cameraController.initialize().then((value) {
      if (!mounted) {
        return;
      }
      setState(() {
        _cameraInitialized = true; // updating the flag after camera is initialized
      }); //To refresh widget
    }).catchError((e) {
      print(e);
    });
  }

@override
  Widget build(BuildContext context) {
    if (_cameraInitialized && cameraController.value.isInitialized) {
      return Scaffold(
        body: Stack(
          children: [
            CameraPreview(cameraController),
          ],
        ),
      );
    } else {
      return SizedBox();
    }
  }

CodePudding user response:

I will suggest using FutureBuilder to handle future method.

class _CameraPageState extends State<CameraPage> {
  late List<CameraDescription> cameras;
  late CameraController cameraController;

  @override
  void initState() {
    super.initState();
  }

  Future<void> startCamera() async {
    cameras = await availableCameras();
    cameraController = CameraController(cameras[0], ResolutionPreset.high);
  }

  late final cameraInit = Future.wait([
    startCamera(),
    cameraController.initialize(),
  ]);
  @override
  void dispose() {
    cameraController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          FutureBuilder(
            future: cameraInit,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                return CameraPreview(cameraController);
              } else {
                return const Center(child: CircularProgressIndicator());
              }
            },
          ),
        ],
      ),
    );
  }
}

Also check this cookbook.

  • Related