【Flutter】Flutter 拍照示例 ( 浮动按钮及点击事件 | 底部显示按钮组件 | 手势检测器组件 | 拍照并获取当前拍摄照片 | 从相册中选择图片 )

2023-03-29 08:46:55 浏览数 (1)

文章目录

  • 一、浮动按钮及点击事件
  • 二、底部显示按钮组件
  • 三、手势检测器组件
  • 四、image_picker 完整代码示例

一、浮动按钮及点击事件


一般使用 Scaffold 组件作为界面的根布局组件 , Scaffold 组件的 floatingActionButton 属性即可设置浮动按钮 , FloatingActionButton 组件 ;

代码语言:javascript复制
// 根组件 
Scaffold(
  // 设置标题组件
  appBar: ,
  // 设置页面主体元素组件 
  body: ,
  // 创建浮动按钮 FloatingActionButton 组件 , 并设置给 floatingActionButton 字段 ; 
  floatingActionButton: FloatingActionButton(),
)

浮动按钮点击事件 : 浮动按钮点击事件就是 FloatingActionButton 组件的 onPressed 属性值 , 设置一个 VoidCallback? 类型的值 ,

代码语言:javascript复制
FloatingActionButton(
  // 浮动按钮点击事件 
  onPressed: () {
  }
)

VoidCallback 就是参数和返回值都是空的函数 ; onPressed: () {} 括号中的参数为空 , 返回值也为空 ;

代码语言:javascript复制
/// Signature of callbacks that have no arguments and return no data.
typedef VoidCallback = void Function();

二、底部显示按钮组件


调用 showModalBottomSheet 方法 , 即可弹出底部按钮组件 , 该组件由开发者定义 , 可以是任何组件 , 如 Column ;

这里在底部显示的是一个 Container 组件 , Container 组件内部包含了一个 Column 组件 ;

代码语言:javascript复制
/// 浮动按钮点击事件
/// 点击浮动按钮 , 弹出一个菜单
/// 菜单有两个按钮 , 分别是 拍照 / 选择图片
showModalBottomSheet(
    context: context,
    builder: (context) {
      return Container(
        // 设置该弹出的组件高度 200 像素
        height: 200,
        child: Column(
          children: <Widget>[
            // 拍照按钮
            GestureDetector(),

            // 相册按钮
            GestureDetector(),
            
          ],
        ),
      );
    });

showModalBottomSheet 方法传入两个必要的参数 , BuildContext context 是上下文对象 , WidgetBuilder builder 是显示的底部布局组件 ;

代码语言:javascript复制
Future<T?> showModalBottomSheet<T>({
  required BuildContext context,
  required WidgetBuilder builder,
  Color? backgroundColor,
  double? elevation,
  ShapeBorder? shape,
  Clip? clipBehavior,
  Color? barrierColor,
  bool isScrollControlled = false,
  bool useRootNavigator = false,
  bool isDismissible = true,
  bool enableDrag = true,
  RouteSettings? routeSettings,
  AnimationController? transitionAnimationController,
})

三、手势检测器组件


这里按钮点击使用 GestureDetector 组件 , 监听器 onTap 方法 , 用户点击时 , 调用 getImageFromCamera 方法 ;

代码语言:javascript复制
GestureDetector(
  child: ListTile(
    // 相机图标
    leading: Icon(Icons.camera_alt),
    title: Text("拍照"),
    /// 按钮点击事件
    onTap: (){
      // 调用 getImage 方法 , 调出相机拍照
      getImageFromCamera();
    },
  ),
),

四、image_picker 完整代码示例


代码示例 :

代码语言:javascript复制
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: '拍照示例'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// 需要导入 dart:io 库
  /// import 'dart:io';
  File _image;

  // 图片获取引擎
  final picker = ImagePicker();

  /// 获取摄像头图像的方法
  Future getImageFromCamera() async {
    /// 菜单按钮消失
    Navigator.pop(context);

    /// 需要导入 image_picker.dart 包
    /// import 'package:image_picker/image_picker.dart';
    final pickedFile =
    await picker.getImage(source: ImageSource.camera);

    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
      } else {
        print('No image selected.');
      }
    });
  }

  /// 获取相册中的图像
  Future getImageFromGallery() async {
    /// 菜单按钮消失
    Navigator.pop(context);

    /// 需要导入 image_picker.dart 包
    /// import 'package:image_picker/image_picker.dart';
    final pickedFile =
    await picker.getImage(source: ImageSource.gallery);

    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
      } else {
        print('No image selected.');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: _image == null ? Text('No image selected.') : Image.file(_image),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          /// 浮动按钮点击事件
          /// 点击浮动按钮 , 弹出一个菜单
          /// 菜单有两个按钮 , 分别是 拍照 / 选择图片
          showModalBottomSheet(
              context: context,
              builder: (context) {
                return Container(
                  // 设置该弹出的组件高度 200 像素
                  height: 200,
                  child: Column(
                    children: <Widget>[
                      // 拍照按钮
                      GestureDetector(
                        child: ListTile(
                          // 相机图标
                          leading: Icon(Icons.camera_alt),
                          title: Text("拍照"),
                          /// 按钮点击事件
                          onTap: (){
                            // 调用 getImage 方法 , 调出相机拍照
                            getImageFromCamera();
                          },
                        ),
                      ),

                      // 相册按钮
                      GestureDetector(
                        child: ListTile(
                          // 相册图标
                          leading: Icon(Icons.photo_library_outlined),
                          title: Text("相册"),
                          /// 按钮点击事件
                          onTap: (){
                            // 调用 getImageFromGallery 方法 , 调出相册
                            getImageFromGallery();

                          },
                        ),
                      ),

                    ],
                  ),
                );
              });
        },
        tooltip: 'Pick Image',
        child: Icon(Icons.add_a_photo),
      ),
    );
  }
}

运行效果 :

五、相关资源


参考资料 :

  • Flutter 官网 : https://flutter.dev/
  • Flutter 插件下载地址 : https://pub.dev/packages
  • Flutter 开发文档 : https://flutter.cn/docs ( 强烈推荐 )
  • 官方 GitHub 地址 : https://github.com/flutter
  • Flutter 中文社区 : https://flutter.cn/
  • Flutter 实用教程 : https://flutter.cn/docs/cookbook
  • Flutter CodeLab : https://codelabs.flutter-io.cn/
  • Dart 中文文档 : https://dart.cn/
  • Dart 开发者官网 : https://api.dart.dev/
  • Flutter 中文网 ( 非官方 , 翻译的很好 ) : https://flutterchina.club/ , http://flutter.axuer.com/docs/
  • Flutter 相关问题 : https://flutterchina.club/faq/ ( 入门阶段推荐看一遍 )

博客源码下载 :

  • GitHub 地址 : https://github.com/han1202012/flutter_photo ( 随博客进度一直更新 , 有可能没有本博客的源码 )
  • 博客源码快照 : https://download.csdn.net/download/han1202012/15852074 ( 本篇博客的源码快照 , 可以找到本博客的源码 )

0 人点赞