Last active
August 29, 2021 16:48
-
-
Save kinmanlam/5755c821413844456e3033421e947772 to your computer and use it in GitHub Desktop.
A refactored camera widget based on the "Take a Picture Using the Camera" cookbook found on flutter.dev. For full walkthru see: https://www.kinmanlam.com/2021/08/flutter-framework-refractored-camera.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:camera/camera.dart'; | |
import 'dart:io'; | |
// A screen that allows users to take a picture using a given camera. | |
class TakePictureScreen extends StatefulWidget { | |
const TakePictureScreen({ | |
Key? key, | |
}) : super(key: key); | |
@override | |
TakePictureScreenState createState() => TakePictureScreenState(); | |
} | |
class TakePictureScreenState extends State<TakePictureScreen> { | |
late CameraController _controller; | |
@override | |
void dispose() { | |
// Dispose of the controller when the widget is disposed. | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@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), | |
), | |
), | |
], | |
); | |
} | |
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(); | |
} | |
} | |
// A widget that displays the picture taken by the user. | |
class DisplayPictureScreen extends StatelessWidget { | |
final String imagePath; | |
const DisplayPictureScreen({Key? key, required this.imagePath}) | |
: super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: const Text('Display the Picture')), | |
// The image is stored as a file on the device. Use the `Image.file` | |
// constructor with the given path to display the image. | |
body: Image.file(File(imagePath)), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment