📜  Flutter – 从存储中挑选并打开文件(1)

📅  最后修改于: 2023-12-03 15:30:48.894000             🧑  作者: Mango

Flutter – 从存储中挑选并打开文件

在 Flutter 开发中,我们经常需要从用户设备的存储中选择和打开文件。Flutter 提供了多种方法来处理此类任务,本篇文章将介绍其中的一些方法。

系统文件选择器

Flutter 提供了一个简单的 widget,可以启动设备的系统文件选择器,供用户选择和打开文件。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';

class FileSelectorPage extends StatefulWidget {
  @override
  _FileSelectorPageState createState() => _FileSelectorPageState();
}

class _FileSelectorPageState extends State<FileSelectorPage> {
  File _selectedFile;

  Future<void> _openFileSelector() async {
    final result = await FilePicker.platform.pickFiles();

    if (result != null) {
      setState(() {
        _selectedFile = File(result.files.first.path);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('文件选择器'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (_selectedFile != null) ...[
              Text('已选择:${_selectedFile.path}'),
              SizedBox(height: 30),
              RaisedButton(
                child: Text('打开文件'),
                onPressed: () async {
                  final bytes = await _selectedFile.readAsBytes();
                  await Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) => FileViewerPage(
                        bytes: bytes,
                        fileName: _selectedFile.path.split('/').last,
                      ),
                    ),
                  );
                },
              ),
            ] else ...[
              Text('未选择文件'),
            ],
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: _openFileSelector,
      ),
    );
  }
}

class FileViewerPage extends StatefulWidget {
  final List<int> bytes;
  final String fileName;

  FileViewerPage({@required this.bytes, @required this.fileName});

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

class _FileViewerPageState extends State<FileViewerPage> {
  Future<String> _getLocalPath() async {
    final directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }

  Future<File> _getLocalFile() async {
    final path = await _getLocalPath();
    return File('$path/${widget.fileName}');
  }

  Future<void> _writeFile() async {
    final file = await _getLocalFile();
    file.writeAsBytes(widget.bytes);
  }

  @override
  void initState() {
    super.initState();
    _writeFile();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.fileName),
      ),
      body: FutureBuilder(
        future: _getLocalFile(),
        builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
          if (snapshot.hasData) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Image.file(snapshot.data),
                ],
              ),
            );
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }
}

代码分析:

整个应用程序分为两个页面:文件选择器页面和文件查看器页面。

  • 文件选择器页面

在文件选择器页面中,我们使用 FilePicker.platform.pickFiles 方法来启动系统文件选择器。获取用户选择的文件之后,我们可以将其保存到 _selectedFile 变量中,并在页面上显示文件路径。

当用户点击“打开文件”按钮时,我们将选择的文件数据传递给文件查看器页面,并通过 Navigator 跳转到该页面。

  • 文件查看器页面

在文件查看器页面中,我们首先需要将文件数据写入设备的本地存储中,以便在显示图片时使用。在 initState 方法中,我们调用 _writeFile 方法将文件数据写入本地文件。

在页面中,我们使用 FutureBuilder 读取本地文件,并通过 Image.file 显示图片。

需要注意的是,在 AndroidManifest.xml 文件中,我们需要添加以下权限声明:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

这些权限用于访问用户设备的外部存储。

结语

通过本文的介绍,我们学习了在 Flutter 中如何使用系统文件选择器选择和打开文件,并从本地存储中读取文件数据。这些技术对于处理与文件相关的任务非常有用,例如文本编辑器、图像浏览器、音频/视频播放器等等。

完整代码片段请看文件中。