Flutter文件管理插件file_manager的使用
Flutter文件管理插件file_manager的使用
简介
file_manager
是一个功能强大的Flutter插件,它允许你管理文件和文件夹、选择文件和文件夹,并且可以执行许多其他操作。该插件设计得就像Flutter框架的一部分一样自然。
GitHub License | Code Size | Top Language | Language Count | Latest Tag | Issues
兼容性
- ✅ Android
- ✅ Linux
- ❌ Windows (正在进行中)
- ❌ MacOS (有活跃问题)
使用方法
安装
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
file_manager: ^1.0.0
给应用程序存储权限
Android
在 android/app/src/main/AndroidManifest.xml
中添加以下权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx.yyy">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"
.../>
</manifest>
你需要运行时请求权限,可以通过 permission_handler
包来实现,或者直接使用 FileManager
请求权限:
await controller.requestFilesAccessPermission();
or
await FileManager.requestFilesAccessPermission();
基本设置
创建 FileManagerController
实例:
final FileManagerController controller = FileManagerController();
示例代码
以下是一个完整的示例代码,展示了如何使用 file_manager
插件:
import 'dart:io';
import 'package:file_manager/file_manager.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.dark,
theme: ThemeData(useMaterial3: true),
darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
final FileManagerController controller = FileManagerController();
@override
Widget build(BuildContext context) {
return ControlBackButton(
controller: controller,
child: Scaffold(
appBar: appBar(context),
body: FileManager(
controller: controller,
builder: (context, snapshot) {
final List<FileSystemEntity> entities = snapshot;
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 0),
itemCount: entities.length,
itemBuilder: (context, index) {
FileSystemEntity entity = entities[index];
return Card(
child: ListTile(
leading: FileManager.isFile(entity)
? Icon(Icons.feed_outlined)
: Icon(Icons.folder),
title: Text(FileManager.basename(
entity,
showFileExtension: true,
)),
subtitle: subtitle(entity),
onTap: () async {
if (FileManager.isDirectory(entity)) {
// 打开文件夹
controller.openDirectory(entity);
} else {
// 执行文件相关任务
}
},
),
);
},
);
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () async {
FileManager.requestFilesAccessPermission();
},
label: Text("Request File Access Permission"),
),
),
);
}
AppBar appBar(BuildContext context) {
return AppBar(
actions: [
IconButton(
onPressed: () => createFolder(context),
icon: Icon(Icons.create_new_folder_outlined),
),
IconButton(
onPressed: () => sort(context),
icon: Icon(Icons.sort_rounded),
),
IconButton(
onPressed: () => selectStorage(context),
icon: Icon(Icons.sd_storage_rounded),
)
],
title: ValueListenableBuilder<String>(
valueListenable: controller.titleNotifier,
builder: (context, title, _) => Text(title),
),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () async {
await controller.goToParentDirectory();
},
),
);
}
Widget subtitle(FileSystemEntity entity) {
return FutureBuilder<FileStat>(
future: entity.stat(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (entity is File) {
int size = snapshot.data!.size;
return Text(
"${FileManager.formatBytes(size)}",
);
}
return Text(
"${snapshot.data!.modified}".substring(0, 10),
);
} else {
return Text("");
}
},
);
}
Future<void> selectStorage(BuildContext context) async {
return showDialog(
context: context,
builder: (context) => Dialog(
child: FutureBuilder<List<Directory>>(
future: FileManager.getStorageList(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final List<FileSystemEntity> storageList = snapshot.data!;
return Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: storageList
.map((e) => ListTile(
title: Text(
"${FileManager.basename(e)}",
),
onTap: () {
controller.openDirectory(e);
Navigator.pop(context);
},
))
.toList()),
);
}
return Dialog(
child: CircularProgressIndicator(),
);
},
),
),
);
}
sort(BuildContext context) async {
showDialog(
context: context,
builder: (context) => Dialog(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Text("Name"),
onTap: () {
controller.sortBy(SortBy.name);
Navigator.pop(context);
}),
ListTile(
title: Text("Size"),
onTap: () {
controller.sortBy(SortBy.size);
Navigator.pop(context);
}),
ListTile(
title: Text("Date"),
onTap: () {
controller.sortBy(SortBy.date);
Navigator.pop(context);
}),
ListTile(
title: Text("Type"),
onTap: () {
controller.sortBy(SortBy.type);
Navigator.pop(context);
}),
],
),
),
),
);
}
createFolder(BuildContext context) async {
showDialog(
context: context,
builder: (context) {
TextEditingController folderName = TextEditingController();
return Dialog(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: TextField(
controller: folderName,
),
),
ElevatedButton(
onPressed: () async {
try {
// 创建文件夹
await FileManager.createFolder(
controller.getCurrentPath, folderName.text);
// 打开创建的文件夹
controller.setCurrentPath =
controller.getCurrentPath + "/" + folderName.text;
} catch (e) {}
Navigator.pop(context);
},
child: Text('Create Folder'),
)
],
),
),
);
},
);
}
}
其他功能
- ControlBackButton: 当当前目录不是根目录时,此小部件注册回调以防止用户关闭窗口或控制系统的返回按钮。
- isFile 和 isDirectory: 检查
FileSystemEntity
是否为文件或目录。 - basename: 获取目录或文件的基本名称。
- formatBytes: 将字节转换为人类可读的大小。
- getFileExtension: 返回文件扩展名。
- getStorageList: 获取设备上的可用存储列表。
- createFolder: 创建目录(如果不存在)。
显示支持和贡献
如果你觉得这个插件对你有帮助,请给它一个星标!
项目由 DevsOnFlutter 创建并维护。
欢迎贡献!如果你有任何改进的想法,请提交Pull Request。
更多关于Flutter文件管理插件file_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文件管理插件file_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于在Flutter中使用file_manager
插件进行文件管理,下面是一个简单的代码案例来展示其基本用法。需要注意的是,file_manager
并不是一个广泛认知的标准Flutter插件,因此我假设你可能是指一个具有类似功能的第三方插件,或者是一个自定义的插件。不过,Flutter生态系统中常用的文件管理插件是path_provider
和file_picker
。由于file_manager
不是标准插件,我将基于path_provider
和file_picker
展示文件管理的基本操作,因为它们是广泛使用的替代方案。
使用path_provider
和file_picker
进行文件管理
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加必要的依赖:
dependencies:
flutter:
sdk: flutter
path_provider: ^2.0.9 # 请检查最新版本
file_picker: ^4.3.3 # 请检查最新版本
然后运行flutter pub get
来安装这些依赖。
2. 获取应用文档目录
使用path_provider
来获取应用的文档目录路径:
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('File Management'),
),
body: Center(
child: FutureBuilder<String>(
future: _getApplicationDocumentsDirectory(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Text('Application documents directory: ${snapshot.data}');
}
} else {
return CircularProgressIndicator();
}
},
),
),
),
);
}
Future<String> _getApplicationDocumentsDirectory() async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
}
3. 使用file_picker
选择文件
接下来,使用file_picker
来让用户选择文件:
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('File Management'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.any,
);
if (result != null) {
FilePickerFile? file = result.files.first;
print('Selected file path: ${file.path}');
// 在这里你可以进一步处理文件,比如读取内容或保存到其他位置
}
},
child: Text('Select File'),
),
],
),
),
),
);
}
}
注意
- 上述代码展示了如何使用
path_provider
获取应用的文档目录路径,并使用file_picker
让用户选择文件。 - 在实际应用中,你可能需要根据所选文件的类型(图片、视频、文档等)进行不同的处理。
- 如果确实有一个名为
file_manager
的插件,并且它提供了特定的功能,你应该参考该插件的官方文档来获取准确的使用方法和示例代码。
希望这个示例能帮助你理解如何在Flutter中进行文件管理。如果有任何进一步的问题,请随时提问!