I need to use camera in two screens when one screen push another screen.
In that case the camera shows black screen when I go back from second widget:
import 'dart:async';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
List<CameraDescription> cameras = [];
late CameraDescription firstCamera;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
firstCamera = cameras.first;
runApp(
MaterialApp(
theme: ThemeData.dark(),
home: TakePictureScreen(
camera: firstCamera,
),
),
);
}
// A screen that allows users to take a picture using a given camera.
class TakePictureScreen extends StatefulWidget {
const TakePictureScreen({
super.key,
required this.camera,
});
final CameraDescription camera;
@override
TakePictureScreenState createState() => TakePictureScreenState();
}
class TakePictureScreenState extends State<TakePictureScreen> {
late CameraController? _controller;
@override
void initState() {
super.initState();
_controller = CameraController(
widget.camera,
ResolutionPreset.medium,
enableAudio: false,
);
_controller?.initialize().then((value) => setState(() {}));
}
@override
void dispose() async {
super.dispose();
await _controller?.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Take a picture')),
body: _controller != null && _controller!.value.isInitialized
? CameraPreview(_controller!)
: const Center(child: CircularProgressIndicator()),
floatingActionButton: FloatingActionButton(
onPressed: () async {
try {
final navigator = Navigator.of(context);
// final oldController = _controller;
// setState(() => _controller = null);
// await oldController?.dispose();
// var cameras = await availableCameras();
// var firstCamera = cameras.first;
await navigator.push(
MaterialPageRoute(
builder: (context) => TakePictureScreen(
camera: firstCamera,
),
),
);
// cameras = await availableCameras();
// firstCamera = cameras.first;
// _controller = CameraController(
// widget.camera,
// ResolutionPreset.medium,
// enableAudio: false,
// );
await _controller?.initialize();
setState(() {});
} catch (e) {
print(e);
}
},
child: const Icon(Icons.camera_alt),
),
);
}
}
I tried everything (see commented out code) but didn’t succeed.
The only way is to pass controller as a parameter, but I can not do it in my project.
There is no such problem on android.
2
Answers
Try to move the camera initialization into a separate _initializeCamera() function to make it easier to call
Properly dispose of the camera controller in the dispose() method of the _TakePictureScreenState class.
Re-initialize the camera controller in the onPressed callback of the floating action button after returning from the second screen.