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


� 1. 引入依赖:pubspec.yaml

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

修改文件pubspec.yaml

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

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 应用

鸿蒙原生系统

系统文件选择器

读取文件流

展示图片

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 选择单个文件。

  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 = []; // 清除多选状态
      });
    }
  }

image-20260202232306070

2.3 实现多图选择功能

文件lib/file_selector_demo.dart

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

  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; // 清除单选状态
      });
    }
  }

image-20260202232426485

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

文件lib/file_selector_demo.dart

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

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

在 Android 或 iOS 上,我们有时可以直接通过文件路径(如 /storage/emulated/0/...)访问文件。
但在鸿蒙(以及现代移动系统)的严格沙箱机制下,应用只能访问自己“私有领地”内的文件。系统选择器返回的路径可能是一个虚拟路径或没有直接读取权限。
使用 readAsBytes() 就像是用一根吸管直接把文件内容“吸”出来,而不需要关心文件具体放在哪,这样既安全又通用!

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

// 单图预览示例
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), // 显示路径仅供参考
],

image-20260202232459168


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

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

修改文件lib/main.dart

操作

  1. 导入演示页面文件。
  2. MyHomePageColumn 中添加一个按钮。
// 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! 💻⚡️
🎉 祝你开发顺利! 🚀
欢迎加入开源鸿蒙跨平台社区

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐