首页 > 解决方案 > 如何从存储中选择多个图像并在 Flutter 和 Flutter Web App 中显示?

问题描述

我正在开发这个 Flutter 应用程序,它允许用户从本地存储中选择多个图像进行上传。选择图像后,它会显示所有图像的预览。

我可以为移动 Flutter 应用程序实现这一点,但我还需要以 Flutter Web 为目标,而这不适用于 Flutter Web。我使用了这个插件,因为它也允许为 Flutter web 选择多个文件,但它正在返回List<html.File>,它不允许我读取图像字节以在 UI 中显示它。

我需要一个解决方案:

标签: flutterflutter-webflutter-plugin

解决方案



您可以在此拉取请求合并之前复制粘贴以下运行完整代码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'),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

推荐阅读