[Flutter]APP拍照功能实现
利用Flutter实现APP拍照功能,效果图具体如下:
- 点击[拍照]按钮
- 选择【拍照】选项,调用设备镜头采集影像
按下快门后,确定选定该影像照片
- 选择【从相册选择】选项,从相册选择照片
- 显示当前选中的照片图像
开发环境:
Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b06b8b2710 (3 months ago) • 2023-01-23 16:55:55 -0800
Engine • revision b24591ed32
Tools • Dart 2.19.0 • DevTools 2.20.1
引用插件:
image_picker: ^0.8.7
以下为具体实现代码:main.dart
代码:
import 'package:flutter/material.dart';
import 'package:blog/photo_app.dart';
void main() {
runApp(const PApp());
}
class PApp extends StatefulWidget {
const PApp({Key? key}) : super(key: key);
@override
State<PApp> createState() => _PAppState();
}
class _PAppState extends State<PApp> {
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: "拍照APP",
home: PhotoApp(title: "拍照APP"),
);
}
}
photo_app.dart
代码:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class PhotoApp extends StatefulWidget {
const PhotoApp({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<PhotoApp> createState() => _PhotoAppState();
}
class _PhotoAppState extends State<PhotoApp> {
late List<XFile> _imageFileList;
void _setImageFileListFromFile(XFile? value) {
if(value != null) {
_imageFileList.add(value);
}
}
@override
void deactivate() {
super.deactivate();
}
@override
void dispose() {
super.dispose();
}
@override
void initState() {
_imageFileList = [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
),
body: Center(
child: Center(
child: Wrap(
spacing: 5,
runSpacing: 5,
children: _genImages(),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _pickImage,
tooltip: "选择图片",
child: const Icon(Icons.add_a_photo),
),
);
}
_pickImage() {
showModalBottomSheet(
context: context,
builder: (context) => Container(
height: 160,
child: Column(
children: [
_item("拍照", true),
_item("从相册选择", false),
],
),
)
);
}
_item(String title, bool isTakePhoto) {
return GestureDetector(
child: ListTile(
leading: Icon(isTakePhoto ? Icons.camera_alt : Icons.photo_library),
title: Text(title),
onTap: () => getImage(isTakePhoto),
),
);
}
Future getImage(bool isTakePhoto) async {
Navigator.pop(context);
final XFile? image = await ImagePicker().pickImage(source: isTakePhoto ? ImageSource.camera : ImageSource.gallery,);
if(image != null) {
setState(() {
_setImageFileListFromFile(image);
});
}
}
_genImages() {
return _imageFileList?.map((file) {
return Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.file(File(file.path), width: 120, height: 120, fit: BoxFit.fill,),
),
Positioned(
right: 5,
top: 5,
child: GestureDetector(
onTap: () {
setState(() {
_imageFileList.remove(file);
});
},
child: ClipOval(
child: Container(
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(color: Colors.black54),
child: Icon(
Icons.close,
size: 18,
color: Colors.yellow,
),
),
),
),
),
],
);
}).toList();
}
}