当 sqflite 数据库数据更改时,Flutter 提供程序监听器不会自行更新

标签 flutter sqlite dart flutter-provider

我使用 flutter sqflite 创建了一个本地数据库。当我在该列表中添加或删除某些内容时,我想听取该数据库上任务列表的长度并更新任务总数。但是当我调用 provider.of(context) 东西时,它不会自行更新,这意味着它不听。我使用 stream 获取数据库数据并显示在 UI 中。

GIF

这是我创建的数据库类:

class TaskDatabase with ChangeNotifier {
  final String dbName = 'db.sqlite';
  Database? _db;

  List<Task> _tasksList = [];
  int _totalTaskCount = 0;
  final _streamController = StreamController<List<Task>>.broadcast();

Stream<List<Task>> all() =>
      _streamController.stream.map((tasks) => tasks..sort());

  int get totalTasksCount {
    return _totalTaskCount;
  }

  Future<bool> close() async {
    final db = _db;
    if (db == null) {
      return false;
    }

    await db.close();
    return true;
  }
    


Future<bool> open() async {
        if (_db != null) {
          return true;
        }
    
    final directory = await getApplicationDocumentsDirectory();
    final path = '${directory.path}/$dbName';

    try {
      final db = await openDatabase(path);
      _db = db;

      //creating the database table using sqflite
      const createTable = '''CREATE TABLE IF NOT EXISTS "TABLEOFTASKS" (
            "id"    INTEGER NOT NULL,
            "taskTitle" TEXT,
            "isDone"    INTEGER NOT NULL DEFAULT 0,
            PRIMARY KEY("id" AUTOINCREMENT));''';

      await db.execute(createTable);

      // read all existing task objects from the db

      _tasksList = await _fetchTasks();
      _streamController.add(_tasksList);
      return true;
    } catch (e) {
      // print('error = $e');
      return false;
    }
  }
 // Creating a new task and save to the database:
 // other CRUD functions are not added here:)

  Future<bool> create(String taskTitle) async {
    final db = _db;
    if (db == null) {
      return false;
    }
    try {
      final id = await db.insert(
        'TABLEOFTASKS',
        {
          'taskTitle': taskTitle,
          'isDone': 0,
        },
      );
      final task = Task(
        id: id,
        taskTitle: taskTitle,
        isDone: false,
      );
      _tasksList.add(task);
      _streamController.add(_tasksList);
      _totalTaskCount = _tasksList.length;
      notifyListeners();
      return true;
    } catch (e) {
      print('error in creating task = $e');
      return false;
    }
  }
}

这是我想收听和更新的小部件:

final int taskCount = Provider.of<TaskDatabase>(context, listen: true).totalTasksCount;
.
.
.
Text(taskCount.toString()),

我在小部件树的顶部添加了 provider 并且没有错误。唯一发生的事情是没有更新 text 小部件

最佳答案

我创建了一个 streamBuilder 并抓取了我想要的列表作为快照。使用 provider 包更新列表长度无效。您可以在问题的 DB 类中找到我如何创建 Tasksstream。 Firest 在 init 方法中初始化 Database

late final TaskDatabase _crudStorage;

  @override
  void initState() {
    _crudStorage = TaskDatabase();
    _crudStorage.open();
    super.initState();
  }

  @override
  void dispose() {
    _crudStorage.close();
    super.dispose();
  }

....

return Scaffold(
      resizeToAvoidBottomInset: false,
      drawer: const CustomDrawer(),
      body: StreamBuilder(
        stream: _crudStorage.all(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.active:
            case ConnectionState.waiting:
              if (snapshot.data == null) {
                return const Center(child: Shimmer());
              }
              final tasksList = snapshot.data as List<Task>; /// The List I want
            .
            .
            .
            .
            .
            .
  SomeTextWidget('The length of tasks = ${tasksList.length}'),

关于当 sqflite 数据库数据更改时,Flutter 提供程序监听器不会自行更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72159431/

相关文章:

c++ - 在 Flutter Windows 桌面应用程序中使用 C++ DLL

android - 在Flutter中找不到参数的方法Implementation()

java - sqlite DB 内带方括号的数据

firebase - 我将flutter应用程序与Firebase集成时出错

dart - 如何在 Flutter 的 State 中使用 2 个 mixin?

flutter - 检查此函数结果的简写是什么?

java - 将Android上的sqlite数据库同步到服务器上的Sybase数据库

c# - 为什么在 Azure Functions 中使用 SQLite 会出现 DLLNotFoundException?

url - 如何获取URL中的查询参数

string - 如何反转 Dart 中的字符串?