Ошибка при заполнении FutureBuilder данными из sqflite - PullRequest
1 голос
/ 01 ноября 2019

У меня есть база данных SQLite с фильмами. Я следую этому примеру.

Я хочу показать все фильмы в ListView.

Я пытаюсь заполнить ListView, используя FutureBuilder как в примере, но когда я назначаю будущее FutureBuilder, оно выдает следующее исключение:

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

Я нахожу это странным, так как моя функция, которую я использую в FutureBuilder, возвращает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(),
                    );
            },
          ),
        ],
      ),
    );
  }

1 Ответ

2 голосов
/ 01 ноября 2019

Метод getAllMovies () не имеет определенного типа возврата, поэтому по умолчанию он вернет:

  1. void : если нетоператор возврата.
  2. динамический : если есть оператор возврата. Int, если он возвращает int, String, если он возвращает String ...

В вашем случае он возвращает список, но dart не знает об этом, пока не будет вызван метод. Для виджета FutureBuilder требуется функция, которая должна явно возвращать список фильмов, а не динамический.

Просто добавьте Список фильмов в качестве типа возврата для 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;
  }
...