【问题标题】:Best way to store objects with images locally on disk in Flutter?在 Flutter 中将带有图像的对象本地存储在磁盘上的最佳方法?
【发布时间】:2021-04-07 09:13:27
【问题描述】:

我正在为一个人制作一个超级简单的食谱(就像字面意思是食物)应用程序,所以我一直没有想过我想要/需要使用数据库或任何互联网连接。当用户创建菜谱时,菜谱对象包含一堆字符串和一张图片,如下所示:

class Recipe {
 String _title;
  Image _picture;
  Uint8List _imageBytes;
  int _prepTime;
  int _cookTime;
  int _totalTime;
  String _description;
  List<String> _ingredientList;
  List<String> _directionsList;


....
}


用户可能会创建大约 20 个食谱。不需要任何个人资料,因为我实际上只是为一个人制作应用程序。配方是唯一需要保留的应用数据。

到目前为止,我已经尝试将每个配方编码为 JSON,然后将其保存到 shared_preferences(请注意我尝试用于此目的的 _imageBytes 字段)。但这不仅看起来是一种非常低效的做事方式,我什至无法让它发挥作用。获取这方面的信息似乎令人困惑:在不使用数据库的情况下,通常如何将这些信息本地存储在 Flutter 应用程序中?或者是数据库的方式去这里?

【问题讨论】:

    标签: flutter sharedpreferences data-persistence


    【解决方案1】:

    您需要路径提供程序包和颤振缓存管理器。

    以下示例演示了如何使用缓存管理器存储网络图像。

    import 'dart:async';
    import 'dart:io' as Io;
    import 'package:image/image.dart';
    
    import 'package:flutter_cache_manager/flutter_cache_manager.dart';
    import 'package:path_provider/path_provider.dart';
    class SaveFile {
    
      Future<String> get _localPath async {
        final directory = await getApplicationDocumentsDirectory();
    
        return directory.path;
      }
      Future<Io.File> getImageFromNetwork(String url) async {
    
        var cacheManager = await CacheManager.getInstance();
        Io.File file = await cacheManager.getFile(url);
        return file;
      }
    
      Future<Io.File> saveImage(String url) async {
    
        final file = await getImageFromNetwork(url);
        //retrieve local path for device
        var path = await _localPath;
        Image image = decodeImage(file.readAsBytesSync());
    
        Image thumbnail = copyResize(image, 120);
    
        // Save the thumbnail as a PNG.
        return new Io.File('$path/${DateTime.now().toUtc().toIso8601String()}.png')
          ..writeAsBytesSync(encodePng(thumbnail));
      }
    }
    

    【讨论】:

      【解决方案2】:

      使用本地数据库(例如SQLite)在 Flutter 中有效地持久化数据是可行的方法:

      1. 导入正确的依赖项:
      import 'dart:async';
      
      import 'package:path/path.dart';
      import 'package:sqflite/sqflite.dart';
      
      1. 打开数据库:
      WidgetsFlutterBinding.ensureInitialized();
      // Open the database and store the reference.
      final Future<Database> database = openDatabase(
        join(await getDatabasesPath(), 'recipes_database.db'),
      );
      
      1. 创建表:
      final Future<Database> database = openDatabase(
        join(await getDatabasesPath(), 'doggie_database.db'),
        onCreate: (db, version) {
          return db.execute(
            "CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TITLE)", // all the properties here
          );
        },
        version: 1,
      );
      
      1. 创建插入和检索条目的方法:
      Future<void> inserRecipe(Recipe recipe) async {
        final Database db = await database;
        await db.insert(
          'recipe',
          recipe.toMap(),
          conflictAlgorithm: ConflictAlgorithm.replace,
        );
      }
      Future<List<Recipe>> recipes() async {
        final Database db = await database;
      
        final List<Map<String, dynamic>> maps = await db.query('recipes');
      
        return List.generate(maps.length, (i) {
          return Recipe(
            title: maps[i]['title'],
            // ... all the properties here
          );
        });
      }
      

      由于我们的类 Recipe 包含文件,更具体地说是图像,我们可以将 Image 存储为 URL 并利用 Cache 来检索它:

      var image = await DefaultCacheManager().getSingleFile(recipe.picture);
      

      【讨论】:

      • 我如何命名 URL 重要吗?
      猜你喜欢
      • 1970-01-01
      • 2011-10-04
      • 2017-01-10
      • 2019-02-13
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      相关资源
      最近更新 更多