Skip to content

Instantly share code, notes, and snippets.

@Kshitij-Dhakal
Created June 3, 2021 15:56
Show Gist options
  • Save Kshitij-Dhakal/5b516422f045be863f6b71f76fff8ae5 to your computer and use it in GitHub Desktop.
Save Kshitij-Dhakal/5b516422f045be863f6b71f76fff8ae5 to your computer and use it in GitHub Desktop.
This is button that shows camera screen when pressed. If you capture image then it will navigate back to original screen and display image just capture instead of button. Image still functions same as button and can be pressed to open camera again. If you already have image in network then you can pass network image to display in place of button.
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
bool isBlank(String? str) => str == null || str.isEmpty;
class OpenCameraButton extends StatelessWidget {
final Function(String imgPath) onCapture;
final String? fileImage;
final String? networkImage;
final double height;
final double width;
final double iconSize;
const OpenCameraButton(
{Key? key,
required this.onCapture,
required this.height,
required this.width,
required this.iconSize,
this.fileImage,
this.networkImage})
: super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: height,
width: width,
child: isBlank(networkImage) && isBlank(fileImage)
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Container(
child: ElevatedButton(
onPressed: () async {
await onPressed(context);
},
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Icon(
Icons.camera_alt,
color: Colors.white,
size: iconSize,
),
),
style: ElevatedButton.styleFrom(
shape: CircleBorder(), primary: Colors.green),
),
),
),
],
)
: _CircularImage(
fileImage: fileImage,
networkImage: networkImage,
onTap: () {
onPressed(context);
},
),
);
}
Future<void> onPressed(BuildContext context) async {
var cameras = await availableCameras();
var img = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CameraScreen(camera: cameras),
),
);
if (img != null) {
onCapture(img);
}
}
}
class _CircularImage extends StatelessWidget {
final String? fileImage;
final String? networkImage;
final Function() onTap;
const _CircularImage({
Key? key,
this.fileImage,
this.networkImage,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
double _imgHeight = 200;
double _imgWidth = 200;
return InkWell(
onTap: onTap,
child: Container(
width: _imgHeight,
height: _imgWidth,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(image: image(), fit: BoxFit.cover),
),
),
);
}
ImageProvider image() {
if (isBlank(fileImage)) {
return NetworkImage(networkImage!);
} else {
return FileImage(File(fileImage!));
}
}
}
class CameraScreen extends StatefulWidget {
static const routeName = '/camera';
final List<CameraDescription> camera;
const CameraScreen({
Key? key,
required this.camera,
}) : super(key: key);
@override
CameraScreenState createState() => CameraScreenState();
}
class CameraScreenState extends State<CameraScreen> {
late CameraController _controller;
Future<void>? _initializeControllerFuture;
@override
void initState() {
super.initState();
_controller = CameraController(
widget.camera.last,
ResolutionPreset.medium,
);
_initializeControllerFuture = _controller.initialize();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void capture() async {
try {
await _initializeControllerFuture;
var xFile = await _controller.takePicture();
Navigator.pop(context, xFile.path);
} on Exception catch (e) {
//TODO handle exception
}
}
Future<void> delete(String imgPath) async {
try {
await File(imgPath).delete();
} catch (e) {
//TODO handle exception
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Column(
children: [
SafeArea(
child: CameraPreview(
_controller,
),
),
Expanded(
child: Center(
child: Ink(
decoration: ShapeDecoration(
color: Colors.white,
shape: CircleBorder(),
),
child: IconButton(
iconSize: 50,
icon: Icon(
Icons.circle,
),
onPressed: capture,
color: Colors.white,
),
),
),
),
],
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment