尝试在 Flutter FutureBuilder 中构建 ListView 时出错
Error trying to build a ListView in a Flutter FutureBuilder
我是 Flutter 的新手,正在构建一个小应用程序来记录我的开支并学习一些知识。
我正在使用 Hive 存储数据。现在我正在构建一个页面,旨在显示所有以前保存的条目。为此,我创建了一个包含所有数据的列表,然后尝试使用 FutureBuilder 在 ListView 中显示数据。
这是目前的代码:
class LogScreen extends StatefulWidget {
const LogScreen({Key? key}) : super(key: key);
@override
_LogScreenState createState() => _LogScreenState();
}
class _LogScreenState extends State<LogScreen> {
get futureEntries => getEntries();
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Widget>(
future: futureEntries,
builder: (BuildContext context, AsyncSnapshot<Widget> snapshot) {
if (snapshot.hasData) {
return Container(
child: ListView.builder(
itemCount: futureEntries.length,
itemBuilder: (context, index) {
Entry currentEntry = Hive.box<Entry>('entriesBox').getAt(index);
return ListTile(
title: Text('${currentEntry.description}'),
);
},
),
);
} else {
return CircularProgressIndicator();
}
}
);
}
Future<List> getEntries() async {
List listEntries = await DbHelper().getListEntries();
print(listEntries);
return listEntries;
}
}
不过我收到以下错误:
The following _TypeError was thrown building LogScreen(dirty, state: _LogScreenState#75644):
type 'Future<List<dynamic>>' is not a subtype of type 'Future<Widget>?'
The relevant error-causing widget was:
LogScreen file:///home/javier/StudioProjects/finanzas/lib/main.dart:55:14
When the exception was thrown, this was the stack:
#0 _LogScreenState.build (package:finanzas/log_screen.dart:29:17)
有人可以告诉我我做错了什么并提出解决方案吗?我来自 Python 并且正在与所有这些类型打交道 :-P
提前致谢。
FutureBuilder<T>()
的通用类型应该对应于您的 Future
将要 return 的数据类型,而不是构建器正在构建的数据类型。在您的情况下,您有 FutureBuilder<Widget>
,因此它期望 Future<Widget>
,但您的 getEntries
return 是 Future<List<dynamic>>
。所以这就是错误所暗示的。您的代码可能应该如下所示:
return FutureBuilder<List<Entry>>(
future: futureEntries,
builder: (BuildContext context, AsyncSnapshot<List<Entry>> snapshot) {
if (snapshot.hasData) {
return Container(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Entry currentEntry = snapshot.data[index];
return ListTile(
title: Text('${currentEntry.description}'),
);
},
),
);
} else {
return CircularProgressIndicator();
}
}
);
另请注意,我将您 ListView.builder
中的引用从直接引用您的未来替换为使用 snapshot
中的数据
好的。经过一些研究,这里是开始工作的代码:
Widget build(BuildContext context) {
return FutureBuilder<List>(
future: futureEntries,
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (snapshot.hasData) {
return Container(
child: ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
Entry currentEntry = snapshot.data![index];
return ListTile(
title: Text('${currentEntry.description}'),
);
},
),
);
} else {
return CircularProgressIndicator();
}
}
);
}
Future<List> getEntries() async {
List listEntries = await DbHelper().getListEntries();
print(listEntries);
return listEntries;
}
我还不知道 'data' 后面的感叹号到底是做什么用的,但他们确实做到了。
我是 Flutter 的新手,正在构建一个小应用程序来记录我的开支并学习一些知识。
我正在使用 Hive 存储数据。现在我正在构建一个页面,旨在显示所有以前保存的条目。为此,我创建了一个包含所有数据的列表,然后尝试使用 FutureBuilder 在 ListView 中显示数据。
这是目前的代码:
class LogScreen extends StatefulWidget {
const LogScreen({Key? key}) : super(key: key);
@override
_LogScreenState createState() => _LogScreenState();
}
class _LogScreenState extends State<LogScreen> {
get futureEntries => getEntries();
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Widget>(
future: futureEntries,
builder: (BuildContext context, AsyncSnapshot<Widget> snapshot) {
if (snapshot.hasData) {
return Container(
child: ListView.builder(
itemCount: futureEntries.length,
itemBuilder: (context, index) {
Entry currentEntry = Hive.box<Entry>('entriesBox').getAt(index);
return ListTile(
title: Text('${currentEntry.description}'),
);
},
),
);
} else {
return CircularProgressIndicator();
}
}
);
}
Future<List> getEntries() async {
List listEntries = await DbHelper().getListEntries();
print(listEntries);
return listEntries;
}
}
不过我收到以下错误:
The following _TypeError was thrown building LogScreen(dirty, state: _LogScreenState#75644):
type 'Future<List<dynamic>>' is not a subtype of type 'Future<Widget>?'
The relevant error-causing widget was:
LogScreen file:///home/javier/StudioProjects/finanzas/lib/main.dart:55:14
When the exception was thrown, this was the stack:
#0 _LogScreenState.build (package:finanzas/log_screen.dart:29:17)
有人可以告诉我我做错了什么并提出解决方案吗?我来自 Python 并且正在与所有这些类型打交道 :-P
提前致谢。
FutureBuilder<T>()
的通用类型应该对应于您的 Future
将要 return 的数据类型,而不是构建器正在构建的数据类型。在您的情况下,您有 FutureBuilder<Widget>
,因此它期望 Future<Widget>
,但您的 getEntries
return 是 Future<List<dynamic>>
。所以这就是错误所暗示的。您的代码可能应该如下所示:
return FutureBuilder<List<Entry>>(
future: futureEntries,
builder: (BuildContext context, AsyncSnapshot<List<Entry>> snapshot) {
if (snapshot.hasData) {
return Container(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Entry currentEntry = snapshot.data[index];
return ListTile(
title: Text('${currentEntry.description}'),
);
},
),
);
} else {
return CircularProgressIndicator();
}
}
);
另请注意,我将您 ListView.builder
中的引用从直接引用您的未来替换为使用 snapshot
好的。经过一些研究,这里是开始工作的代码:
Widget build(BuildContext context) {
return FutureBuilder<List>(
future: futureEntries,
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (snapshot.hasData) {
return Container(
child: ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
Entry currentEntry = snapshot.data![index];
return ListTile(
title: Text('${currentEntry.description}'),
);
},
),
);
} else {
return CircularProgressIndicator();
}
}
);
}
Future<List> getEntries() async {
List listEntries = await DbHelper().getListEntries();
print(listEntries);
return listEntries;
}
我还不知道 'data' 后面的感叹号到底是做什么用的,但他们确实做到了。