flutter - 如何从存储中选择多个图像并在 Flutter 和 Flutter Web App 中显示?
问题描述
我正在开发这个 Flutter 应用程序,它允许用户从本地存储中选择多个图像进行上传。选择图像后,它会显示所有图像的预览。
我可以为移动 Flutter 应用程序实现这一点,但我还需要以 Flutter Web 为目标,而这不适用于 Flutter Web。我使用了这个插件,因为它也允许为 Flutter web 选择多个文件,但它正在返回List<html.File>
,它不允许我读取图像字节以在 UI 中显示它。
我需要一个解决方案:
- 允许选择多个图像
- 也适用于颤振网络
- 允许访问图像字节数据,以便我可以显示它们的预览
解决方案
您可以在此拉取请求合并之前复制粘贴以下运行完整代码https://github.com/miguelpruivo/flutter_file_picker/pull/328/files/3e23d4e9977451d4e84f54a155ac1b2a951cd7fe
代码片段
Future<List<int>> fileAsBytes(html.File _file) async {
final Completer<List<int>> bytesFile = Completer<List<int>>();
final html.FileReader reader = html.FileReader();
reader.onLoad.listen((event) => bytesFile.complete(reader.result));
reader.readAsArrayBuffer(_file);
return await bytesFile.future;
}
ListView.separated(
itemBuilder: (BuildContext context, int index) =>
Column(
children: [
FutureBuilder<List<int>>(
future: fileAsBytes(_files[index]),
builder: (context, snapshot) => snapshot.hasData
? Image.memory(snapshot.data)
: CircularProgressIndicator()),
Text("name ${_files[index].name}"),
],
),
工作演示
选择两个图像文件并显示,不检查文件类型是图像
完整代码
// ignore: avoid_web_libraries_in_flutter
import 'dart:async';
import 'dart:html';
import 'package:file_picker_web/file_picker_web.dart';
import 'package:flutter/material.dart';
import 'dart:html' as html;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<html.File> _files = [];
Future<List<int>> fileAsBytes(html.File _file) async {
final Completer<List<int>> bytesFile = Completer<List<int>>();
final html.FileReader reader = html.FileReader();
reader.onLoad.listen((event) => bytesFile.complete(reader.result));
reader.readAsArrayBuffer(_file);
return await bytesFile.future;
}
void _pickFiles() async {
_files = await FilePicker.getMultiFile() ?? [];
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: _files.isNotEmpty
? ListView.separated(
itemBuilder: (BuildContext context, int index) =>
Column(
children: [
FutureBuilder<List<int>>(
future: fileAsBytes(_files[index]),
builder: (context, snapshot) => snapshot.hasData
? Image.memory(snapshot.data)
: CircularProgressIndicator()),
Text("name ${_files[index].name}"),
],
),
itemCount: _files.length,
separatorBuilder: (_, __) => const Divider(
thickness: 5.0,
),
)
: Center(
child: Text(
'Pick some files',
textAlign: TextAlign.center,
),
),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: RaisedButton(
onPressed: _pickFiles,
child: Text('Pick Files'),
),
)
],
),
),
),
);
}
}
推荐阅读
- python - 通过 Django 发送电子邮件 - WinError 10060 连接尝试失败和 GetAddrInfo 错误
- python - 缩放数组(sklearn) - python
- python - Tkinter 新创建的按钮不执行命令
- swift - Firestore:使用数组比较进行查询
- nginx - 如何将 nginx 反向代理从根域设置到另一个域中的特定路径?
- java - 两个活动之间的共享数组列表不起作用
- regex - XML 中的正则表达式
- tfs - Visual Studio 测试 V2 未在多个代理上分发测试 - TFS 2018
- c# - 将Excel文件读入数据库
- c# - 循环为多列设置 OrderBy/ThenBy