使用 sqflite 中的数据填充 FutureBuilder 时出错

Error when populating FutureBuilder with data from sqflite

我有一个包含电影的 SQLite 数据库。我正在关注 this 示例。

我想在 ListView 中显示所有电影。

我尝试像示例中那样使用 FutureBuilder 填充 ListView,但是在我分配 FutureBuilder 的未来的地方,它会抛出以下异常:

type 'Future<dynamic>' is not a subtype of type 'Future<List<Movie>>'

我觉得这很奇怪,因为我在 FutureBuilder returns a List<Movie> 而不是 dynamic.

中使用的函数

可能导致此错误的原因是什么?

数据库:

class MovieDatabase {
  MovieDatabase._();
  static final MovieDatabase db = MovieDatabase._();
  static Database _database;

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

  initDB() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, "MovieDB.db");
    return await openDatabase(path, version: 1, onOpen: (db) {},
        onCreate: (Database db, int version) async {
      await db.execute("CREATE TABLE Movie ("
          ...
          ")");
    });
  }

  getAllMovies() async {
    final db = await database;
    var res = await db.query("Movie");
    List<Movie> list =
        res.isNotEmpty ? res.map((m) => Movie.fromSqLite(m)).toList() : [];
    return list;
  }
  ...
}

小部件:

@override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: <Widget>[
          FutureBuilder<List<Movie>>(
            future: MovieDatabase.db.getAllMovies(), // This line causes the error
            initialData: List(),
            builder:
                (BuildContext context, AsyncSnapshot<List<Movie>> snapshot) {
              return snapshot.hasData
                  ? ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (BuildContext context, int position) {
                        Movie movie = snapshot.data[position];
                        return Card(
                          child: ListTile(
                            title: Text(movie.title),
                          ),
                        );
                      },
                    )
                  : Center(
                      child: CircularProgressIndicator(),
                    );
            },
          ),
        ],
      ),
    );
  }

方法 getAllMovies() 没有特定的 return 类型,因此默认情况下,它将 return:

  1. void:如果没有return语句。
  2. dynamic:如果有return语句。 Int 如果它 returns int,String 如果它 returns String...

在你的例子中,它是 returning 一个列表,但 dart 在调用该方法之前不知道。小部件 FutureBuilder 需要一个函数,该函数需要显式 return 电影列表,而不是动态。

只需将 电影列表 作为 return 类型添加到 getAllMovies() 方法中,您就可以开始:

 List<Movies> getAllMovies() async {
    final db = await database;
    var res = await db.query("Movie");
    List<Movie> list =
        res.isNotEmpty ? res.map((m) => Movie.fromSqLite(m)).toList() : [];
    return list;
  }