Recent

Sunday, August 29, 2021

Flutter Framework - Refractored Camera Widget

For those who are new to the Flutter Framework and looking to learn and use the camera, the Take a picture using the camera cookbook is a great place to start.

I followed the instructions and it worked fine. The next step for me was to refactor the code so that the camera widget was in its own dart file.


How to Avoid Getting "LateInitializationError: Field 'controller' has not been initialized" Error

The key is to create async function to wait for the camera to be fully initialized and use it with the already written FutureBuilder.

Future<void> initCamera() async {
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
firstCamera,
// Define the resolution to use.
ResolutionPreset.medium,
);

// Next, initialize the controller. This returns a Future.
await _controller.initialize();
}

Then use it in the build method like this:

@override
Widget build(BuildContext context) {
// Fill this out in the next steps.
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
FutureBuilder<void>(
future: initCamera(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return CameraPreview(_controller);
} else {
// Otherwise, display a loading indicator.
return const Center(child: CircularProgressIndicator());
}
},
),
Expanded(
child: FloatingActionButton(
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
// Ensure that the camera is initialized.
await initCamera();

// Attempt to take a picture and get the file `image`
// where it was saved.
final image = await _controller.takePicture();

// If the picture was taken, display it on a new screen.
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(
// Pass the automatically generated path to
// the DisplayPictureScreen widget.
imagePath: image.path,
),
),
);
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
child: const Icon(Icons.camera_alt),
),
),
],
);
}


Full Source Code of Camera Widget

For full source code of the camera.dart file: https://gist.github.com/kinmanlam/5755c821413844456e3033421e947772

How To Use It?

If you simply want to start experimenting with the camera widget, take the camera.dart, add it to your existing Flutter project. In the body field of a Scaffold add the TakePictureScreen() widget.

1 comment: