通过 FutureBuilder 访问 Sqflite 数据的 Flutter 问题。 ConnectionState.done, 空
Flutter problem with access to Sqflite data via FutureBuilder. ConnectionState.done, null
正在尝试更改对数据库的访问权限:
只是初始化对数据的访问 initState
,然后在 ListView.builder
中显示结果
至
ListView.builder
里面的FutureBuilder
.
但是我在这个 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();
}
...
在您的 updateAndGetList
函数中,您应该 return 一个 Future<List<Word>>
。相反,您不 return 任何东西(而是设置状态)。考虑将其调整为如下所示:
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
,然后在 ListView.builder
至
ListView.builder
里面的FutureBuilder
.
但是我在这个 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();
}
...
在您的 updateAndGetList
函数中,您应该 return 一个 Future<List<Word>>
。相反,您不 return 任何东西(而是设置状态)。考虑将其调整为如下所示:
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: ...
);