【问题标题】:Flutter problem with access to Sqflite data via FutureBuilder. ConnectionState.done, null通过 FutureBuilder 访问 Sqflite 数据的颤振问题。 ConnectionState.done,空
【发布时间】:2022-01-05 12:59:21
【问题描述】:

尝试从以下位置更改对数据库的访问权限:

只需初始化对数据initState的访问,然后在ListView.builder中显示结果

ListView.builderFutureBuilder 内。

但是我在这个 FutureBuilder 中迷路了,我的列表是空的。我想我的问题在updateAndGetList() 内部。 在控制台中我得到了这个:

flutter: AsyncSnapshot<List<Word>>(ConnectionState.done, null, , #0      _RandomWordsState.updateAndGetList.<anonymous closure> (package:myapplesson/main.dart:115:7)

有人可以帮助或推动我朝着正确的方向前进吗????

这是我的 main.dart

DatabaseHelper dbHelper = DatabaseHelper.instance;
final _suggestions = <Word>[];

  @override
  void initState() {
    super.initState();
    // initial load
    _listFuture = updateAndGetList();
  }

  late Future<List<Word>> _listFuture;

  void refreshList() {
    // reload
    setState(() {
      _listFuture = updateAndGetList();
    });
  }

//I GUESS I AM DOING SOMETHING WRONG HERE!?????????????

  Future<List<Word>> updateAndGetList() async {
    await DatabaseHelper.instance.database;
    // return the list here
    return dbHelper.getAllWords().then((rows) {
      setState(() {
        rows?.forEach((row) { _suggestions.add(Word.map(row));});
      });
      throw '';
    });
  }

  Widget _buildSuggestions() {
    return FutureBuilder<List<Word>>(
      future: _listFuture,
      builder: (BuildContext context, AsyncSnapshot<List<Word>> snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
            itemCount: _suggestions.length,
            itemBuilder: (context, i) {
              if (i.isOdd) return const Divider();
              final index = i ~/ 2;
              if (index >= _suggestions.length) {
                _suggestions.addAll(_suggestions.take(10));
              }
              return _buildRow(_suggestions[index]);
            });
        }else if (snapshot.hasError) {
          return Text("Oops!");
        }
        return Center(child: CircularProgressIndicator());
      },
    );
  }

Widget _buildRow(Word pair) {
  return ListTile(
    title: Text(
      pair.word1
    ),
    subtitle: Text(
        pair.meaning
    ),
  );
}

在更改完成之前,一切都是这样进行的:

//perfectly worked????

@override
void initState() {
  super.initState();
  dbHelper.getAllWords().then((rows) {
    setState(() {
      rows?.forEach((row) { _suggestions.add(Word.map(row));});
    });
  });
}

Widget _buildSuggestions() {
  return ListView.builder(
      itemCount: _suggestions.length,
      itemBuilder: (context, i) {
        if (i.isOdd) return const Divider();
        final index = i ~/ 2;
        if (index >= _suggestions.length) {
          _suggestions.addAll(_suggestions.take(10));
        }
        return _buildRow(_suggestions[index]);
      });
}
Widget _buildRow(Word pair) {
  return ListTile(
    title: Text(
      pair.word1
    ),
    subtitle: Text(
        pair.meaning
    ),
  );
}

这是我的 Database_helper.dart

...
Future<List<Map<String, dynamic>>?> getAllWords() async {
    Database? db = await instance.database;
    var result = await db?.query(table);
    return result?.toList();
  }
...

【问题讨论】:

    标签: flutter dart sqflite flutter-futurebuilder


    【解决方案1】:

    在您的updateAndGetList 函数中,您应该返回一个Future&lt;List&lt;Word&gt;&gt;。相反,您不返回任何内容(而是设置状态)。考虑将其调整为如下所示:

      Future<List<Word>> updateAndGetList() async {
        await DatabaseHelper.instance.database;
        // return the list here
        return dbHelper.getAllWords().then((rows) {
          // build the list of words and then return it!
          List<Word> res = [];
          for (var row in rows) {
            res.add(Word.map(row));;      
          }
          return res;
        });
      }
    

    您现在可以在未来的构建器中从快照中访问此单词列表

    return FutureBuilder<List<Word>>(
          future: _listFuture,
          builder: (BuildContext context, AsyncSnapshot<List<Word>> snapshot) {
            if (snapshot.hasData) {
              
              // the word list as retrieved from your future
              List<Word> wordList = snapshot.data;
              return ListView.builder(
                itemCount: wordList.length,
                itemBuilder: (context, i) {
                  if (i.isOdd) return const Divider();
                  final index = i ~/ 2;
                  if (index >= wordList.length) {
                    wordList.addAll(wordList.take(10));
                  }
                  // use the word listto build your rows
                  return _buildRow(wordList[index]);
                });
            }else if (snapshot.hasError) {
              return Text("Oops!");
            }
            return Center(child: CircularProgressIndicator());
          },
        );
    

    无需为您的建议保留单独的变量。

    此外,您实际上并不需要您的 _listFuture 变量,除非您在其他地方需要它。在您的FutureBuilder 中,您可以简单地使用

    return FutureBuilder<List<Word>>(
      future: updateAndGetList(),
      builder: ...
    );
    

    【讨论】:

    • 啊,好的!我在那里感到困惑。以前我只是在 InitState 中设置了状态,并且已经获得了完全的访问权限。但是在我的函数中并非如此,我不得不返回我的列表:_suggestions。是的,确实代码看起来是多余的。但是,也许使用变量 _suggestions 仍然是一种很好的做法,因为从现在开始,我想显示过滤后的列表,以便将输入输入到我的搜索栏中。 _suggestions.where((text)...非常感谢!
    猜你喜欢
    • 2021-09-25
    • 2018-11-18
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    相关资源
    最近更新 更多