在Flutter中重新启动后再次检索SQLLite注解记录

v09wglhw  于 6个月前  发布在  Flutter
关注(0)|答案(1)|浏览(61)

编辑:看来这个错误只发生在“重新启动”,并没有发生在热重新加载。
我面临的问题,已经从SQLLite数据库中删除的笔记重新启动后又回来了。我不知道为什么会发生这种情况,例如,我删除一个笔记,然后重新启动应用程序,相同的笔记重新出现在屏幕上。这很奇怪,因为以前我使用相同的代码删除了笔记,它们没有回来,它们永远消失了。
有什么想法为什么会发生这种情况吗?似乎笔记在删除后会留在数据库中,然后一旦数据库被检索到,它们就会回来,但我检查了一下,每次都会调用await数据库.delete()。

import 'package:flutter/material.dart';
import 'package:notepad/screens/Note.dart';
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

//Singleton
class DatabaseProvider {
  static Database? _database;
  static bool _isDatabaseInitialized = false;

  static Future<Database> get database async {
    if (_isDatabaseInitialized) {
      return _database!;
    }
    _database = await _initDatabase();
    _isDatabaseInitialized = true;
    return _database!;
  }

  static Future<Database> _initDatabase() async {
    // Set the path to the database. Note: Using the `join` function from the
    // `path` package is best practice to ensure the path is correctly
    // constructed for each platform.
    final path = join(await getDatabasesPath(), 'notes.db');
    return await openDatabase(
      path,
      // When the database is first created, create a table to store notes.
      onCreate: (db, version) {
        // Run the CREATE TABLE statement on the database.
        return db.execute(
          'CREATE TABLE Notes(id INTEGER PRIMARY KEY, title TEXT, subtitle TEXT)',
        );
      },
      // Set the version. This executes the onCreate function and provides a
      // path to perform database upgrades and downgrades.
      version: 1,
    );
  }
}

class ListOfNotes extends StatefulWidget {
  const ListOfNotes({super.key});

  @override
  State<ListOfNotes> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<ListOfNotes> {
  bool _isInitialized = false;

  var noteTitle = [];
  var noteContent = [];

  late var originalNoteTitle = [];
  late var originalNoteContent = [];

  late var isSelected =
      List<bool>.filled(noteTitle.length, false, growable: true);
  late var tileColor =
      List<Color>.filled(noteTitle.length, Colors.white, growable: true);

  var appBarActionsEnabled = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
          itemCount: noteTitle.length,
          prototypeItem: ListTile(
            contentPadding: EdgeInsets.all(10),
            title:
                Text(noteTitle.firstWhere((element) => true, orElse: () => '')),
            subtitle: Text(
                noteContent.firstWhere((element) => true, orElse: () => '')),
          ),
          itemBuilder: (context, index) {
            return ListTile(
                title: Text(noteTitle[index]),
                subtitle: Text(noteContent[index]),
                onLongPress: () {
                  toggleSelection(index);
                  toggleActions();
                },
                onTap: () {
                  _editNote(context, index);
                },
                selected: isSelected[index],
                tileColor: tileColor[index],
                enabled: true);
          }),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          _navigateAndDisplaySelection(context);
        },
      ),
    );
  }

  Future<void> deleteSelectedNotes() async {
    final database = await DatabaseProvider.database;
    // Remove the Note from the database.
    for (int i = 0; i < noteTitle.length; i++) {
      if (isSelected[i] == true) {
        await database.delete(
          'Notes',
          // Use a `where` clause to delete a specific note.
          where: 'id = ?',
          // Pass the Note's id as a whereArg to prevent SQL injection.
          whereArgs: [i],
        );
      }
    }
    setState(() {
      for (int i = 0; i < isSelected.length; i++) {
        if (isSelected[i] == true) {
          noteTitle.removeAt(i);
          noteContent.removeAt(i);
          originalNoteTitle.removeAt(i);
          originalNoteContent.removeAt(i);
          isSelected.removeAt(i);
          tileColor.removeAt(i);
        }
      }
    });
  }
@override
  void initState() {
    super.initState();
    _initializeNotes();
  }

  Future<void> _initializeNotes() async {
    if (!_isInitialized) {
      await _retrieveNotes();
      _isInitialized = true;
    }
  }

  Future<void> _retrieveNotes() async {
    var tempNoteTitleWait = [];
    var tempNoteContentWait = [];

    final database = await DatabaseProvider.database;

    final List<Map<String, dynamic>> result = await selectNotesDB(database);

    for (final row in result) {
      tempNoteTitleWait.add(row['title']);
      tempNoteContentWait.add(row['subtitle']);
    }

    setState(() {
      noteTitle = List<String>.from(tempNoteTitleWait);
      noteContent = List<String>.from(tempNoteContentWait);
      originalNoteTitle = List<String>.from(tempNoteTitleWait);
      originalNoteContent = List<String>.from(tempNoteContentWait);
    });
  }

字符串

p3rjfoxz

p3rjfoxz1#

原来我使用的数据库和列表上一定有一些不同的索引,所以作为一个半措施,我使用了title[index],它似乎工作。我不知道为什么它不删除两个相同标题的笔记,而这样做,但它的工作原理,所以我猜这将是一个托德霍华德“它只是工作”的示例。

Future<void> deleteSelectedNotes() async {
  final database = await DatabaseProvider.database;

  List<int> indicesToDelete = [];
  // Remove the Note from the database.
  for (int i = 0; i < isSelected.length; i++) {
    if (isSelected[i] == true) {
      await database.delete(
        'Notes',
        // Use a `where` clause to delete a specific note.
        where: 'title = ?',
        // Pass the Note's id as a whereArg to prevent SQL injection
        whereArgs: [noteTitle[i]],
      );

      indicesToDelete.add(i);
    }
  }

字符串

相关问题