首页 > 解决方案 > 下载 ZIP,解压缩并显示图像文件,但未从文档目录加载?

问题描述

你好朋友我正在创建项目,当用户首先安装我的应用程序时,他们从互联网下载 zip 文件并提取其中的所有文件然后显示在我的应用程序中,但问题是当用户下载并提取文件时,当我关闭应用程序时,应用程序中显示的 zip 中的图像并再次重新打开它 每次他们需要单击下载按钮时都不会从文档目录加载图像然后在应用程序中显示图像有人告诉我这里有什么问题是代码吗?

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:archive/archive.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
 
class DownloadAssetsDemo extends StatefulWidget {
  DownloadAssetsDemo() : super();
 
  final String title = "Download & Extract ZIP Demo";
 
  @override
  DownloadAssetsDemoState createState() => DownloadAssetsDemoState();
}
 
class DownloadAssetsDemoState extends State<DownloadAssetsDemo> {
  //
  bool _downloading;
  String _dir;
  List<String> _images, _tempImages;
  String _zipPath = 'https://coderzheaven.com/youtube_flutter/images.zip';
  String _localZipFileName = 'images.zip';
 
  @override
  void initState() {
    super.initState();
    _images = List();
    _tempImages = List();
    _downloading = false;
    _initDir();
  }
 
  _initDir() async {
    if (null == _dir) {
      _dir = (await getApplicationDocumentsDirectory()).path;
    }
  }
 
  Future<File> _downloadFile(String url, String fileName) async {
    var req = await http.Client().get(Uri.parse(url));
    var file = File('$_dir/$fileName');
    return file.writeAsBytes(req.bodyBytes);
  }
 
  Future<void> _downloadZip() async {
    setState(() {
      _downloading = true;
    });
 
    _images.clear();
    _tempImages.clear();
 
    var zippedFile = await _downloadFile(_zipPath, _localZipFileName);
    await unarchiveAndSave(zippedFile);
 
    setState(() {
      _images.addAll(_tempImages);
      _downloading = false;
    });
  }
 
  unarchiveAndSave(var zippedFile) async {
    var bytes = zippedFile.readAsBytesSync();
    var archive = ZipDecoder().decodeBytes(bytes);
    for (var file in archive) {
      var fileName = '$_dir/${file.name}';
      if (file.isFile) {
        var outFile = File(fileName);
        //print('File:: ' + outFile.path);
        _tempImages.add(outFile.path);
        outFile = await outFile.create(recursive: true);
        await outFile.writeAsBytes(file.content);
      }
    }
  }
 
  buildList() {
    return Expanded(
      child: ListView.builder(
        itemCount: _images.length,
        itemBuilder: (BuildContext context, int index) {
          return Image.file(
            File(_images[index]),
            fit: BoxFit.fitWidth,
          );
        },
      ),
    );
  }
 
  progress() {
    return Container(
      width: 25,
      height: 25,
      padding: EdgeInsets.fromLTRB(0.0, 20.0, 10.0, 20.0),
      child: CircularProgressIndicator(
        strokeWidth: 3.0,
        valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
      ),
    );
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          _downloading ? progress() : Container(),
          IconButton(
            icon: Icon(Icons.file_download),
            onPressed: () {
              _downloadZip();
            },
          ),
        ],
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            buildList(),
          ],
        ),
      ),
    );
  }
}

标签: flutterdart

解决方案


您可以在下面复制粘贴运行完整代码您可以使用包 代码片段
保存和恢复List<String>SharedPreferences

getHistoryImageList() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _images = prefs.getStringList("images");
    });
  }
...
Future<void> _downloadZip() async {
    ...
    await unarchiveAndSave(zippedFile);

    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setStringList("images", _tempImages);
    setState(() {
      _images = List<String>.from(_tempImages);
      _downloading = false;
    });
  }

工作演示

在此处输入图像描述

完整代码

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:archive/archive.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

class DownloadAssetsDemo extends StatefulWidget {
  DownloadAssetsDemo() : super();

  final String title = "Download & Extract ZIP Demo";

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

class DownloadAssetsDemoState extends State<DownloadAssetsDemo> {
  //
  bool _downloading;
  String _dir;
  List<String> _images, _tempImages;
  String _zipPath = 'https://coderzheaven.com/youtube_flutter/images.zip';
  String _localZipFileName = 'images.zip';

  getHistoryImageList() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _images = prefs.getStringList("images");
    });
  }

  @override
  void initState() {
    super.initState();
    _images = [];
    getHistoryImageList();
    _tempImages = List();
    _downloading = false;
    _initDir();
  }

  _initDir() async {
    if (null == _dir) {
      _dir = (await getApplicationDocumentsDirectory()).path;
      print("init $_dir");
    }
  }

  Future<File> _downloadFile(String url, String fileName) async {
    var req = await http.Client().get(Uri.parse(url));
    var file = File('$_dir/$fileName');
    print("file.path ${file.path}");
    return file.writeAsBytes(req.bodyBytes);
  }

  Future<void> _downloadZip() async {
    setState(() {
      _downloading = true;
    });

    _images?.clear();
    _tempImages?.clear();

    var zippedFile = await _downloadFile(_zipPath, _localZipFileName);
    await unarchiveAndSave(zippedFile);

    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setStringList("images", _tempImages);
    setState(() {
      _images = List<String>.from(_tempImages);
      _downloading = false;
    });
  }

  unarchiveAndSave(var zippedFile) async {
    var bytes = zippedFile.readAsBytesSync();
    var archive = ZipDecoder().decodeBytes(bytes);
    for (var file in archive) {
      var fileName = '$_dir/${file.name}';
      print("fileName ${fileName}");
      if (file.isFile && !fileName.contains("__MACOSX")) {
        var outFile = File(fileName);
        //print('File:: ' + outFile.path);
        _tempImages.add(outFile.path);
        outFile = await outFile.create(recursive: true);
        await outFile.writeAsBytes(file.content);
      }
    }
  }

  buildList() {
    return _images == null
        ? Container()
        : Expanded(
            child: ListView.builder(
              itemCount: _images.length,
              itemBuilder: (BuildContext context, int index) {
                return Image.file(
                  File(_images[index]),
                  fit: BoxFit.fitWidth,
                );
              },
            ),
          );
  }

  progress() {
    return Container(
      width: 25,
      height: 25,
      padding: EdgeInsets.fromLTRB(0.0, 20.0, 10.0, 20.0),
      child: CircularProgressIndicator(
        strokeWidth: 3.0,
        valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          _downloading ? progress() : Container(),
          IconButton(
            icon: Icon(Icons.file_download),
            onPressed: () {
              _downloadZip();
            },
          ),
        ],
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            buildList(),
          ],
        ),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: DownloadAssetsDemo(),
    );
  }
}

推荐阅读