Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'package:camera/camera.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:module_core/widgets/camera_overlay/overlay_shape.dart';
- typedef XFileCallback = void Function(XFile file);
- class CameraOverlay extends StatefulWidget {
- const CameraOverlay({
- required this.camera,
- required this.onCapture,
- Key? key,
- this.flash = false,
- this.enableCaptureButton = true,
- this.label,
- this.info,
- this.loadingWidget,
- this.infoMargin,
- }) : super(key: key);
- final CameraDescription camera;
- final bool flash;
- final bool enableCaptureButton;
- final XFileCallback onCapture;
- final String? label;
- final String? info;
- final Widget? loadingWidget;
- final EdgeInsets? infoMargin;
- @override
- State<CameraOverlay> createState() => _FlutterCameraOverlayState();
- }
- class _FlutterCameraOverlayState extends State<CameraOverlay>
- with WidgetsBindingObserver {
- _FlutterCameraOverlayState();
- late CameraController controller;
- @override
- void initState() {
- super.initState();
- WidgetsBinding.instance.addObserver(this);
- controller = CameraController(
- widget.camera,
- ResolutionPreset.high,
- );
- controller.initialize().then((_) {
- if (!mounted) {
- return;
- }
- setState(() {});
- }).catchError((Object e) {
- if (e is CameraException) {
- switch (e.code) {
- case 'CameraAccessDenied':
- break;
- case 'CameraAccessDeniedWithoutPrompt':
- // iOS only
- break;
- case 'CameraAccessRestricted':
- // iOS only
- break;
- case 'AudioAccessDenied':
- break;
- case 'AudioAccessDeniedWithoutPrompt':
- // iOS only
- break;
- case 'AudioAccessRestricted':
- // iOS only
- break;
- default:
- // _showCameraException(e);
- break;
- }
- }
- });
- }
- @override
- void didUpdateWidget(oldWidget) {
- super.didUpdateWidget(oldWidget);
- controller.dispose();
- }
- @override
- void dispose() {
- controller.dispose();
- WidgetsBinding.instance.removeObserver(this);
- super.dispose();
- }
- @override
- void didChangeAppLifecycleState(AppLifecycleState state) {
- if (!controller.value.isInitialized) {
- return;
- }
- if (state == AppLifecycleState.inactive) {
- controller.dispose();
- } else if (state == AppLifecycleState.resumed) {
- onNewCameraSelected(controller.description);
- }
- }
- Future<void> onNewCameraSelected(CameraDescription cameraDescription) async {
- // await controller.dispose();
- controller = CameraController(
- cameraDescription,
- ResolutionPreset.high,
- );
- controller.addListener(() {
- if (mounted) {
- setState(() {});
- }
- if (controller.value.hasError) {
- //if error
- }
- });
- try {
- await controller.initialize();
- } on CameraException catch (e) {
- switch (e.code) {
- case 'CameraAccessDenied':
- break;
- case 'CameraAccessDeniedWithoutPrompt':
- // iOS only
- break;
- case 'CameraAccessRestricted':
- // iOS only
- break;
- case 'AudioAccessDenied':
- break;
- case 'AudioAccessDeniedWithoutPrompt':
- // iOS only
- break;
- case 'AudioAccessRestricted':
- // iOS only
- break;
- default:
- // _showCameraException(e);
- break;
- }
- }
- if (mounted) {
- setState(() {});
- }
- }
- @override
- Widget build(BuildContext context) {
- Widget loadingWidget = widget.loadingWidget ??
- const Center(
- child: CircularProgressIndicator(
- color: Colors.orangeAccent,
- ),
- );
- if (!controller.value.isInitialized) {
- return loadingWidget;
- }
- controller
- .setFlashMode(widget.flash == true ? FlashMode.auto : FlashMode.off);
- // to normal camera stretched
- var camera = controller.value;
- final size = MediaQuery.of(context).size;
- var scale = size.aspectRatio * camera.aspectRatio;
- if (scale < 1) scale = 1 / scale;
- return Stack(
- alignment: Alignment.bottomCenter,
- fit: StackFit.expand,
- children: [
- Transform.scale(
- scale: scale,
- child: Center(
- child: CameraPreview(controller),
- ),
- ),
- const OverlayShape(),
- if (widget.label != null || widget.info != null)
- Align(
- alignment: Alignment.topCenter,
- child: Container(
- margin: widget.infoMargin ??
- const EdgeInsets.only(top: 100, left: 20, right: 20),
- child: Column(
- children: [
- if (widget.label != null)
- Text(
- widget.label ?? 'label',
- style: const TextStyle(
- color: Colors.white,
- fontSize: 24,
- fontWeight: FontWeight.w700,
- ),
- ),
- if (widget.info != null)
- Flexible(
- child: Text(
- widget.info ?? 'info',
- textAlign: TextAlign.center,
- style: const TextStyle(
- color: Colors.white,
- fontSize: 16,
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- if (widget.enableCaptureButton)
- Align(
- alignment: Alignment.bottomCenter,
- child: Material(
- color: Colors.transparent,
- child: Container(
- decoration: const BoxDecoration(
- color: Colors.black12,
- shape: BoxShape.circle,
- ),
- margin: const EdgeInsets.all(25),
- child: IconButton(
- color: Colors.white,
- onPressed: () async {
- for (int i = 10; i > 0; i--) {
- await HapticFeedback.vibrate();
- }
- XFile file = await controller.takePicture();
- widget.onCapture(file);
- },
- icon: const Icon(
- Icons.circle,
- ),
- iconSize: 72,
- ),
- ),
- ),
- ),
- ],
- );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement