当我重新启动应用程序时,笔记正在显示,我能够保存但无法从数据库动态获取保存的笔记。我正在使用 sqflite

Posted

技术标签:

【中文标题】当我重新启动应用程序时,笔记正在显示,我能够保存但无法从数据库动态获取保存的笔记。我正在使用 sqflite【英文标题】:I am able to save but not able to fetch the saved notes dynamically from DB, when I restart the app the notes are displaying. I am using sqflite 【发布时间】:2021-11-07 00:53:36 【问题描述】:

我是 Flutter 的初学者,我正在构建一个简单的笔记应用程序,用户可以在其中输入、编辑和保存笔记到本地数据库中。我可以将笔记保存到数据库,但保存后不会立即获取。我需要重新启动应用程序才能看到笔记列表。 这是一个 Notes 模型类

import 'db_operations.dart';

class Note 
   int id;
   String title;
   String body;

  Note(this.id, this.title, this.body);

  Note.fromMap(Map<String, dynamic> map) 
    id = map['id'];
    title = map['title'];
    body = map['body'];
  

  Map<String, dynamic> toMap()
    return 
      DatabaseHelper.columnId : id,
      DatabaseHelper.columnTitle : title,
      DatabaseHelper.columnBody : body
    ;
  

  @override
  String toString()
    return 'Notetitle : $title, body : $body';
  

这是一个数据库助手类

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'model_notes.dart';

class DatabaseHelper 

  static final _databaseName = "myNote.db";
  static final _databaseVersion = 1;
  static final table = 'notes_table';
  static final columnId = 'id';
  static final columnTitle = 'title';
  static final columnBody = 'body';

  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database _database;
  Future<Database> get database async 
    if (_database != null) return _database;
    // lazily instantiate the db the first time it is accessed
    _database = await initDatabase();
    return _database;
  

  initDatabase() async 
    String path = join(await getDatabasesPath(), _databaseName);
    return await openDatabase(path,
        version: _databaseVersion,
        onCreate: _onCreate);
  
  Future _onCreate(Database db, int version) async 
    await db.execute('''
          CREATE TABLE $table (
            $columnId INTEGER PRIMARY KEY AUTOINCREMENT,
            $columnTitle TEXT NOT NULL,
            $columnBody TEXT NOT NULL
          )
          ''');
  

  Future<int> insert(Note note) async 
    Database db = await instance.database;
    if (note.title.trim().isEmpty) note.title = 'Untitled Note';
    return await db.insert(table, 'title': note.title, 'body': note.body);
  
  Future<List<Note>> getNotesFromDB() async 
    final db = await database;
    List<Note> notesList = [];
    List<Map> maps = await db.query(table);
    if (maps.length > 0) 
      maps.forEach((map) 
        notesList.add(Note.fromMap(map));
      );
    
    return notesList;
  

这是我添加注释的地方

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:note_taking_app/constants/buttons_and_icons_misc(classes).dart';
import 'package:note_taking_app/db/db_operations.dart';
import 'package:note_taking_app/db/model_notes.dart';
import 'package:sqflite/sqflite.dart';
import 'main_screen.dart';

final bodyController = TextEditingController();
final headerController = TextEditingController();
final dbHelper = DatabaseHelper.instance;

class AddingNotes extends StatefulWidget 
  @override
  _AddingNotesState createState() => _AddingNotesState();


class _AddingNotesState extends State<AddingNotes> 

  @override
  void initState() 
    super.initState();
    bodyController.clear();
    headerController.clear();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backwardsCompatibility: true,
        leading: LeadingIcon(
          callBack: () 
            Navigator.pop(context);
          ,
        ),
        backgroundColor: Colors.white.withOpacity(0.4),
        actions: <Widget>[
          ActionsIconButton(
            icon: Icon(undo, color: black),
            callBack: () 
              debugPrint('undo tapped');
            ,
          ),
          ActionsIconButton(
            icon: Icon(redo, color: black),
            callBack: () 
              debugPrint('redo tapped');
            ,
          ),
          ActionsIconButton(
            icon: Icon(save, color: black),
            callBack: () async 
              debugPrint(bodyController.text);
              debugPrint(headerController.text);
              String title = headerController.text;
              String body =  bodyController.text;
              Note note = Note(20, title, body);
              var value = await dbHelper.insert(note);
              print("if 1 is return then insert success and 0 then not inserted : $value");
              Navigator.pop(context);
            ,
          )
        ],
      ),
      body: Container(
        color: Colors.white.withOpacity(0.4),
        child: Padding(
          padding: const EdgeInsets.all(13.0),
          child: Column(
            children: [
              HeaderBody(
                textEditingController: headerController,
              ),
              SizedBox(
                height: 32.0,
              ),
              Expanded(
                child: NotesBody(
                  textEditingController: bodyController,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  

这是我显示笔记的地方

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:note_taking_app/constants/text_and_decorations(methods).dart';
import 'package:note_taking_app/db/model_notes.dart';
import 'package:note_taking_app/ui/adding_notes.dart';
import 'package:note_taking_app/db/db_operations.dart';

class MainScreen extends StatefulWidget 
  @override
  _MainScreenState createState() => _MainScreenState();


class _MainScreenState extends State<MainScreen> 

  List<Note> noteList = [];

  @override
  void initState() 
    super.initState();
    dbHelper.initDatabase();
    setNotesFromDB();
  

  setNotesFromDB() async
    print("Entered setNotes");
    var fetchedNotes = await dbHelper.getNotesFromDB();
    setState(() 
      noteList = fetchedNotes;
    );


  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        title: titleText,
        backwardsCompatibility: false,
        automaticallyImplyLeading: false,
        backgroundColor: Colors.white.withOpacity(0.4),
      ),
      floatingActionButton: Container(
        height: 80.0,
        width: 80.0,
        child: FittedBox(
          child: FloatingActionButton(
            onPressed: () 
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => AddingNotes()));
            ,
            child: const Icon(
              Icons.add,
            ),
            backgroundColor: Colors.green,
          ),
        ),
      ),
      body: ListView.builder(
        itemCount: noteList.length,
        itemBuilder: (context, index)
          return ListTile(
            title: Text('$noteList[index]'),
          );
        ,
      ),

    );
  

当我重新启动应用程序时,我会收到用户输入的注释。我怎样才能使这个动态,当用户输入并保存它时,它应该显示在主屏幕上。但我不知道该怎么做。任何帮助在这里,我被困在这个..

【问题讨论】:

【参考方案1】:

问题是你使用的是future,一旦完成就不会更新,除非调用getNotesFromDB()的Widget被重建,当你重新启动应用程序或模拟器时就是这种情况。

此外,您也只是获取 MainScreen 的 initState() 中的注释。

选项 1: 尝试将正文中的 ListView.builder 转换为流构建器,它会在保存新注释时刷新屏幕。

选项 2: 或者,实现一个拉动刷新逻辑,它会为您调用getNotesFromDB()。从 FlutterTeam 签出 this video 以实现该功能。

【讨论】:

以上是关于当我重新启动应用程序时,笔记正在显示,我能够保存但无法从数据库动态获取保存的笔记。我正在使用 sqflite的主要内容,如果未能解决你的问题,请参考以下文章

CoreData 仅在我重新启动应用程序后更新?

ipython笔记本关闭后保存变量

保存我的唯一 ID(字符串)并稍后在我重新启动 Java 应用程序时检索它

用户杀死Android应用后保存状态

Jupyter笔记本 - Dead Kernel

应用程序重新启动时数组未保存。持久数据的问题