我这样用鸿蒙化Flutter三方库file_selector实现单图片和多图片选择

你好!👋 欢迎来到这篇关于 file_selector 在 HarmonyOS (OpenHarmony) 上使用的实战教程。


� 1. 引入依赖:pubspec.yaml

首先,我们需要在项目的配置文件中引入适配后的 file_selector 库。

修改文件pubspec.yaml

操作 :在 dependencies 节点下添加 file_selector 的 git 依赖配置。

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter
  
  # 👇 新增:引入 file_selector 鸿蒙适配版本
  file_selector: 
    git:
      url: https://gitcode.com/openharmony-tpc/flutter_packages.git
      path: packages/file_selector/file_selector
      ref: br_file_selector-v1.0.3_ohos

💡 提示 :修改完成后,别忘了运行终端命令 flutter pub get 来下载依赖!

👶 新手小课堂:为什么通过 Git 引入?

通常我们使用 pub.dev 上的库,但由于鸿蒙适配版本目前还处于早期阶段或由社区维护,可能尚未合并到官方主仓库或发布到公共仓库。

因此,我们需要使用 git 方式直接指向代码仓库和特定的分支 (ref),这样就能抢先体验适配后的功能啦!


🛠️ 2. 核心功能实现:lib/file_selector_demo.dart

接下来,我们创建一个全新的文件 lib/file_selector_demo.dart,用于集中实现文件选择和预览的核心逻辑。

2.1 导入必要的包

文件lib/file_selector_demo.dart

我们需要导入 file_selector 库以及用于处理二进制数据的 dart:typed_data
调用 openFile
Platform Channel
唤起
用户选择文件
返回文件信息
readAsBytes
Image.memory
用户点击选择
Flutter 应用
鸿蒙原生系统
系统文件选择器
读取文件流
展示图片

dart 复制代码
import 'package:flutter/material.dart';
import 'package:file_selector/file_selector.dart'; // 👈 核心库
import 'dart:typed_data'; // 👈 用于处理文件流

2.2 实现单图选择功能

文件lib/file_selector_demo.dart

我们在 _FileSelectorDemoPageState 类中定义 _pickImage 方法。使用 XTypeGroup 限制文件类型,并调用 openFile 选择单个文件。

dart 复制代码
  XFile? _singleImage; // 用于存储单选结果

  Future<void> _pickImage() async {
    // 定义允许选择的文件类型(图片)
    const XTypeGroup typeGroup = XTypeGroup(
      label: 'images',
      extensions: <String>['jpg', 'png', 'gif'],
    );
    
    // 🚀 调用 openFile 唤起文件选择器
    final XFile? file = await openFile(acceptedTypeGroups: <XTypeGroup>[typeGroup]);

    if (file != null) {
      setState(() {
        _singleImage = file;
        _multiImages = []; // 清除多选状态
      });
    }
  }

2.3 实现多图选择功能

文件lib/file_selector_demo.dart

类似地,定义 _pickMultiImages 方法,调用 openFiles 接口实现批量选择。

dart 复制代码
  List<XFile> _multiImages = []; // 用于存储多选结果

  Future<void> _pickMultiImages() async {
    const XTypeGroup typeGroup = XTypeGroup(
      label: 'images',
      extensions: <String>['jpg', 'png', 'gif'],
    );
    
    // 🚀 调用 openFiles 选择多个文件
    final List<XFile> files = await openFiles(acceptedTypeGroups: <XTypeGroup>[typeGroup]);

    if (files.isNotEmpty) {
      setState(() {
        _multiImages = files;
        _singleImage = null; // 清除单选状态
      });
    }
  }

2.4 实现图片预览(✨ 关键点)

文件lib/file_selector_demo.dart

在鸿蒙系统上,由于文件沙箱机制的差异,推荐使用文件流(Bytes)的方式来加载图片,而不是直接使用文件路径。

👶 新手小课堂:为什么不能直接用文件路径?

在 Android 或 iOS 上,我们有时可以直接通过文件路径(如 /storage/emulated/0/...)访问文件。

但在鸿蒙(以及现代移动系统)的严格沙箱机制 下,应用只能访问自己"私有领地"内的文件。系统选择器返回的路径可能是一个虚拟路径或没有直接读取权限。

使用 readAsBytes() 就像是用一根吸管直接把文件内容"吸"出来,而不需要关心文件具体放在哪,这样既安全又通用!

我们使用 FutureBuilder 配合 file.readAsBytes() 来实现预览:

dart 复制代码
// 单图预览示例
if (_singleImage != null) ...[
  const Text('Selected Image:', style: TextStyle(fontWeight: FontWeight.bold)),
  FutureBuilder<Uint8List>(
    future: _singleImage!.readAsBytes(), // 👈 关键:读取文件流
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
        // 使用 Image.memory 展示图片
        return Image.memory(
          snapshot.data!,
          height: 200,
        );
      } else if (snapshot.hasError) {
        return const Text('Error loading image');
      } else {
        return const CircularProgressIndicator();
      }
    },
  ),
  Text(_singleImage!.path), // 显示路径仅供参考
],

🚀 3. 配置应用入口:lib/main.dart

最后,我们在应用的主页添加入口,跳转到我们刚刚写的演示页面。

修改文件lib/main.dart

操作

  1. 导入演示页面文件。
  2. MyHomePageColumn 中添加一个按钮。
dart 复制代码
// 1. 导入头文件
import 'file_selector_demo.dart'; 

// ...

// 2. 在 build 方法中添加跳转按钮
ElevatedButton(
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const FileSelectorDemoPage()),
    );
  },
  child: const Text('Go to File Selector Demo'),
),

🎉 结语

通过以上三个文件的简单配置,我们就完成了 file_selector 在鸿蒙系统上的集成!🚀

  • pubspec.yaml:引入"入场券"。
  • lib/file_selector_demo.dart:搭建"舞台",实现选择与预览。
  • lib/main.dart:打开"大门",连接新功能。

快去运行你的鸿蒙应用试试吧!Happy Coding! 💻⚡️

🎉 祝你开发顺利! 🚀
欢迎加入开源鸿蒙跨平台社区

相关推荐
听麟2 小时前
HarmonyOS 6.0+ PC端视频剪辑工具开发实战:Media Kit进阶与硬件加速渲染落地
华为·harmonyos
浩宇软件开发2 小时前
基于OpenHarmony鸿蒙开发医院预约挂号系统(前端后端分离)
前端·华为·harmonyos
牛马1112 小时前
flutter Riverpod 中的 overrideWith
android·java·flutter
牛马1112 小时前
flutter riverpod AsyncNotifier 和 Notifier
flutter
不爱吃糖的程序媛3 小时前
如何判断Flutter三方库是否需要OHOS适配开发?附完整适配指导
flutter·华为·harmonyos
小雨下雨的雨3 小时前
HarmonyOS 应用开发实战:高精图像处理与头像裁剪持久化技术深度解析
图像处理·人工智能·华为·ai·交互·harmonyos·鸿蒙系统
讯方洋哥3 小时前
HarmonyOS App开发——职前通应用App开发(上)
华为·harmonyos
kirk_wang3 小时前
Flutter艺术探索-Flutter渲染管道:RenderObject与Layer深度解析
flutter·移动开发·flutter教程·移动开发教程
江湖有缘3 小时前
基于华为openEuler部署Sqliteviz轻量级SQLite可视化工具
jvm·华为·sqlite