【问题标题】:Flutter Persist Image in SQFLiteSQFLite 中的颤振持久化图像
【发布时间】:2021-05-10 01:13:03
【问题描述】:

我尝试了很多,但没有为我的问题找到答案或无法适应它(我对 Flutter 的了解并不深)。

我有一个日记,我将条目存储为文本。这很好用! 所以,我想添加一个相机/图像选择器,您可以在其中将图片添加到日记条目并将其与 SQFLite 中的文本一起保存。 所以相机/图像选择器也很好用。但我不能坚持图像。每次我重新打开日记条目时,都没有图像。 以下是我的代码:

这是我的页面,我在其中添加日记条目。 (我整理了一下,以便更好地了解它

import 'dart:ffi';
import 'dart:io' as Io;
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'dart:async';
import 'dart:ui';
///import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:date_format/date_format.dart';
import 'package:fischapp/Impressum.dart';
import 'package:fischapp/ReadTodoScreen.dart';
import 'package:fischapp/TimeDate.dart';
import 'package:fischapp/main.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'Todo.dart';
import 'DatabaseHelper.dart';
import 'ImageUploadModel.dart';
import 'dart:convert';





class DetailTodoScreen extends StatefulWidget {
  static const routeName = '/detailTodoScreen';
  final Todo todo;

  const DetailTodoScreen({Key key, this.todo}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _CreateTodoState(todo);


}


class _CreateTodoState extends State<DetailTodoScreen> {
  Todo todo;
  final descriptionTextController = TextEditingController();
  final titleTextController = TextEditingController();



  _CreateTodoState(this.todo);



  @override
  void initState() {
    super.initState();
    if (todo != null) {
      descriptionTextController.text = todo.content;
      titleTextController.text = todo.title;
    }
    }

  @override
  void dispose() {
    super.dispose();
    descriptionTextController.dispose();
    titleTextController.dispose();
  }


  Future<File> imageFile;




  File _image;
  @override
  void initState4() {
    super.initState();
  }

  void open_camera()
  async {
    var image = await ImagePicker.pickImage(source: ImageSource.camera);
    setState(() {
      _image = image;
    });

  }
  void open_gallery()
  async {
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image = image;
    });
  }


  File _avatarImg;

  void _getImage(BuildContext context, ImageSource source) {
    ImagePicker.pickImage(
      source: source,
      maxWidth: 400.0,
      maxHeight: 400.0,
    ).then((File image) {
      _avatarImg = image;
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
     appBar: AppBar(
        title: Text('Neuer Tagebucheintrag'),
      ),
      body: ListView(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: TextField(
              decoration: InputDecoration(
                  border: OutlineInputBorder(), labelText: "Titel"),
              maxLines: 1,
              controller: titleTextController,
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: TextField(
              decoration: InputDecoration(
                  border: OutlineInputBorder(), labelText: "Kurzbeschreibung"),
              maxLines: 5,
              controller: descriptionTextController,
            ),
          ),
          ),
          FlatButton(
            color: Colors.deepOrangeAccent,
            child: Text("Open Camera", style: TextStyle(color: Colors.white),),
            onPressed: (){

              open_camera();

            },),
          FlatButton(
            color: Colors.limeAccent,

            child:Text("Open Gallery", style: TextStyle(color: Colors.black),),
            onPressed: (){
              open_gallery();
            },
          ),
          Container(
            color: Colors.black12,
            height: 500.0,
            width: 900.0,
            child: _image == null ? Text("Hier wird das Bild dargestellt!") : Image.file(_image),
          ),
          ]),
      floatingActionButton: FloatingActionButton(
          child: Icon(Icons.check),
          onPressed: () async {
            _saveTodo(titleTextController.text, descriptionTextController.text);
            setState(() {});
          }),
    );
  }

  _saveTodo(String title, String content)
        async {
     if (todo == null) {
      DatabaseHelper.instance.insertTodo(Todo(
          title: titleTextController.text,
          content: descriptionTextController.text,

      ));
      Navigator.pop(context, "Your todo has been saved.");
    } else {
      await DatabaseHelper.instance
          .updateTodo(Todo(id: todo.id, title: title, content: content));
      Navigator.pop(context);
      setState(() {
        ReadTodoScreen();
      });
    }
  }
}

我将描述和标题存储为带有控制器的文本并将其提供给 sqflite。 使用 FloatingActionButton,我调用 saveTodo 函数来存储它。 函数 saveTodo 调用然后 DataBaseHelper。

这是我的 DatabaseHelper 类。

import 'package:flutter/cupertino.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

import 'Todo.dart';

class DatabaseHelper {
  //Create a private constructor
  DatabaseHelper._();

  static const databaseName = 'todos_database.db';
  static final DatabaseHelper instance = DatabaseHelper._();
  static Database _database;

  Future<Database> get database async {
    if (_database == null) {
      return await initializeDatabase();
    }
    return _database;
  }

  initializeDatabase() async {
    return await openDatabase(join(await getDatabasesPath(), databaseName),
        version: 1, onCreate: (Database db, int version) async {
      await db.execute(
          "CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title TEXT, content TEXT");
    });
  }

  insertTodo(Todo todo) async {
    final db = await database;
    var res = await db.insert(Todo.TABLENAME, todo.toMap(),
        conflictAlgorithm: ConflictAlgorithm.replace);
    return res;
  }

  Future<List<Todo>> retrieveTodos() async {
    final db = await database;

    final List<Map<String, dynamic>> maps = await db.query(Todo.TABLENAME);

    return List.generate(maps.length, (i) {
      return Todo(
        id: maps[i]['id'],
        title: maps[i]['title'],

      );
    });
  }

  updateTodo(Todo todo) async {
    final db = await database;

    await db.update(Todo.TABLENAME, todo.toMap(),
        where: 'id = ?',
        whereArgs: [todo.id],
        conflictAlgorithm: ConflictAlgorithm.replace);
  }

  deleteTodo(int id) async {
    var db = await database;
    db.delete(Todo.TABLENAME, where: 'id = ?', whereArgs: [id]);
  }
}

至少,初始化变量的 ToDo 类:

import 'dart:typed_data';

class Todo {
  final int id;
  final String content;
  final String title;

  static const String TABLENAME = "todos";

  Todo({this.id, this.content, this.title});

  Map<String, dynamic> toMap() {
    return {'id': id, 'content': content, 'title': title};
  }
}

我尝试将其存储为 BLOB,但没有成功。既不是 BASE64 字符串。 :( 我听说使用 BASE64 字符串会增加大小,但这没关系。

我希望,这就是你所需要的。 非常感谢!!

【问题讨论】:

    标签: javascript android flutter dart


    【解决方案1】:

    我认为您应该使用 Shared Preferences 或 Hive 包来保存图像或其他比 String 更大的值。 Sqflite 不太愿意这样做。

    将图像保存到本地存储的示例:

    1. First Video
    2. Second Video

    如果这些解决方案不适合您,您可以查看另一个 StackOverflow 问题的答案;如何使用 Sqflite 将图像保存到本地存储。 here

    【讨论】:

    • 感谢您的回答,但我尝试使用 sqflite 解决它。以共同的偏好构建新的需要很长时间,或者你有一个(工作的)例子吗?
    • 不客气!你问过一个共享偏好的例子吗?
    • 在这里,我粘贴了 2 个关于如何使用共享首选项将图像保存到本地存储的 youtube 视频。在下方,您可以看到另一个 StackOverflow 问题链接;如何使用 Sqflite 将图像保存到本地存储。
    • 非常感谢。我尝试了您的链接中的解决方案,但它对我不起作用。我可以试试你的 YT 视频。谢谢!
    • 不客气,伙计!
    猜你喜欢
    • 2020-06-01
    • 2020-02-26
    • 2018-10-25
    • 2021-10-12
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    相关资源
    最近更新 更多