我们在做一些图片上传的场景时,会用到在相册选择图片上传的功能,想在flutter中实现这一功能还是比较简单的,不需要申请权限,即可拉起相册。需要用到的插件是image_picker。

打开flutter鸿蒙SDK的兼容库链接,在里面搜索image_picker:

GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/openharmony-tpc/flutter_packages/blob/master/README.md#openharmony%E5%B9%B3%E5%8F%B0%E5%B7%B2%E5%85%BC%E5%AE%B9%E5%BA%93

选择适合你的项目版本的点进去,然后将代码下载到本地

我们在vs code中打开这个示例项目:

首次打开项目,需执行flutter pub get下载依赖包,然后将没有必要的目录删掉,然后项目基本上就不会爆红了:

然后执行flutter run,看到签名提示后,去dev eco给ohos包自动签名:

签名完成后,我们再次执行flutter run,然后可以成功执行:

然后,我们代码,将里面有用的方法抽离出来,做一个简单的封装,形成一个imageUtil工具类:


import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker_example/main.dart';
import 'package:image_picker_ohos/image_picker_ohos.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
import 'package:video_player/video_player.dart';

class ImageUtil{
List<XFile>? _mediaFileList;

  void _setImageFileListFromFile(XFile? value) {
    _mediaFileList = value == null ? null : <XFile>[value];
  }

  // bool _isVideo = false;
  VideoPlayerController? _controller;
  VideoPlayerController? _toBeDisposed;

  final ImagePickerPlatform _picker = new ImagePickerOhos();
  final TextEditingController maxWidthController = TextEditingController();
  final TextEditingController maxHeightController = TextEditingController();
  final TextEditingController qualityController = TextEditingController();
  final TextEditingController limitController = TextEditingController();

T? _firstOrNull<T>(List<T> list) {
  return list.isEmpty ? null : list.first;
}


    Future<void> onImageButtonPressed(
    ImageSource source, {
    required BuildContext context,
    bool isVideo =false,
    bool isMultiImage = false,
    bool isMedia = false,
  }) async {
    if (_controller != null) {
      await _controller!.setVolume(0.0);
    }
    if (context.mounted) {
      if (isVideo) {
        final XFile? file = await _picker.getVideo(
            source: source, maxDuration: const Duration(seconds: 10));
        if (file != null && context.mounted) {
          _showPickedSnackBar(context, <XFile>[file]);
        }
        await _playVideo(file);
      } else if (isMultiImage) {
        await _displayPickImageDialog(context, true, (double? maxWidth,
            double? maxHeight, int? quality, int? limit) async {
      
            final ImageOptions imageOptions = ImageOptions(
              maxWidth: maxWidth,
              maxHeight: maxHeight,
              imageQuality: quality,
            );
            final List<XFile> pickedFileList = isMedia
                ? await _picker.getMedia(
                    options: MediaOptions(
                      allowMultiple: isMultiImage,
                      imageOptions: imageOptions,
                      limit: limit,
                    ),
                  )
                : await _picker.getMultiImageWithOptions(
                    options: MultiImagePickerOptions(
                      imageOptions: imageOptions,
                      limit: limit,
                    ),
                  );
            if (pickedFileList.isNotEmpty && context.mounted) {
              _showPickedSnackBar(context, pickedFileList);
            }
         
          
        });
      } else if (isMedia) {
        await _displayPickImageDialog(context, false, (double? maxWidth,
            double? maxHeight, int? quality, int? limit) async {
 
            final List<XFile> pickedFileList = <XFile>[];
            final XFile? media = _firstOrNull(await _picker.getMedia(
              options: MediaOptions(
                  allowMultiple: isMultiImage,
                  imageOptions: ImageOptions(
                    maxWidth: maxWidth,
                    maxHeight: maxHeight,
                    imageQuality: quality,
                  )),
            ));

            if (media != null) {
              pickedFileList.add(media);
     
            }
         
        });
      } else {
        await _displayPickImageDialog(context, false, (double? maxWidth,
            double? maxHeight, int? quality, int? limit) async {
 
            final XFile? pickedFile = await _picker.getImageFromSource(
              source: source,
              options: ImagePickerOptions(
                maxWidth: maxWidth,
                maxHeight: maxHeight,
                imageQuality: quality,
              ),
            );
            if (pickedFile != null && context.mounted) {
              _showPickedSnackBar(context, <XFile>[pickedFile]);
            }
          
        });
      }
    }
  }

    void _showPickedSnackBar(BuildContext context, List<XFile> files) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text('Picked: ${files.map((XFile it) => it.name).join(',')}'),
      duration: const Duration(seconds: 2),
    ));
  }




_displayPickImageDialog(
      BuildContext context, bool isMulti, OnPickImageCallback onPick)  {
         final double? width = maxWidthController.text.isNotEmpty
                        ? double.parse(maxWidthController.text)
                        : null;
                    final double? height = maxHeightController.text.isNotEmpty
                        ? double.parse(maxHeightController.text)
                        : null;
                    final int? quality = qualityController.text.isNotEmpty
                        ? int.parse(qualityController.text)
                        : null;
                    final int? limit = limitController.text.isNotEmpty
                        ? int.parse(limitController.text)
                        : null;
                    onPick(width, height, quality, limit);
    
  }
    Future<void> _playVideo(XFile? file) async {
    if (file != null ) {
      await _disposeVideoController();
      late VideoPlayerController controller;

      controller = VideoPlayerController.file(File(file.path));
      _controller = controller;
      const double volume = 1.0;
      await controller.setVolume(volume);
      await controller.initialize();
      await controller.setLooping(true);
      await controller.play();
      // setState(() {});
    }
  }

    Future<void> _disposeVideoController() async {
    if (_toBeDisposed != null) {
      await _toBeDisposed!.dispose();
    }
    _toBeDisposed = _controller;
    _controller = null;
  }
}


ImageUtil imageUtil = ImageUtil();

调用也比较简单:

imageUtil.onImageButtonPressed(ImageSource.camera, context: context);
功能:打开设备相机
说明:调用设备的相机应用,让用户拍摄一张照片,context是当前的上下文环境


imageUtil.onImageButtonPressed(ImageSource.gallery, context: context);
功能:打开图片库(相册)
说明:从设备的图片库中选择一张图片,默认可能只允许选择图片


imageUtil.onImageButtonPressed(ImageSource.gallery, context: context, isMultiImage: true, isMedia: true);
功能:多选媒体文件
说明:从图库中可以选择多个文件,isMultiImage: true允许多选,isMedia: true表示可以选择所有类型的媒体文件(图片和视频)

imageUtil.onImageButtonPressed(ImageSource.gallery, context: context, isMedia: true);
功能:选择单个媒体文件
说明:从图库中选择单个媒体文件(可以是图片或视频),但不能多选


imageUtil.onImageButtonPressed(ImageSource.gallery, context: context,isMultiImage: true,);
功能:多选图片
说明:从图库中选择多张图片,但不包括视频


imageUtil.onImageButtonPressed(ImageSource.gallery, context: context,isVideo: true);
功能:选择单个视频
说明:从图库中专门选择一个视频文件


imageUtil.onImageButtonPressed(ImageSource.camera, context: context,isVideo: true);
功能:打开相机录制视频
说明:调用设备相机应用,但切换到视频录制模式,让用户录制一段视频

效果如图:

以上是个人经验分享。

Logo

加入「COC·上海城市开发者社区」,成就更好的自己!

更多推荐