使用 Flutter FutureBuilder 迭代 JSON 中的对象数组
Iterating over an array of objects in JSON with Flutter FutureBuilder
我在尝试使用 Flutter 的 FutureBuilder 从远程 URL 遍历 JSON 对象数组时遇到问题。
我的目标是:
- 从 API
中获取 JSON 数据
- 将数据输出到 2 列网格视图布局中
JSON 数据是一个对象数组(或 dart 中的地图列表),对象具有简单的字符串数据。
我知道我需要构建一个未来来从 API 获取数据并解码 JSON,然后我需要创建一个 FutureBuilder 来将列表数据输出到我的 Gridview Builder .这就是我在下面的代码中尝试做的事情。
import 'dart:convert';
import 'dart:async';
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class HomeSection extends StatefulWidget {
@override
_HomeSectionState createState() => _HomeSectionState();
}
class _HomeSectionState extends State<HomeSection> {
@override
void initState() {
super.initState();
}
Future<List<dynamic>> fetchSectionData() async {
String dataUrl =
'https://www.thisisthejsonapilink.co.uk/fetch-data';
var response = await http.get(Uri.parse(dataUrl));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to get the data');
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: fetchSectionData,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return GridView.builder(
itemCount: 12,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300,
crossAxisSpacing: 16.0,
mainAxisSpacing: 18.0,
childAspectRatio: MediaQuery.of(context).size.height / 930,
),
itemBuilder: (BuildContext context, int index) => GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OtherScreen()),
);
},
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 12.0),
height: 144,
),
Text(
snapshot.data[index].title,
),
Text(
snapshot.data[index].duration + ' - ' + snapshot.data[index].type,
),
],
),
),
);
} else {
return Center(
child: CircularProgressIndicator(
color: Colors.black,
),
);
}
},
);
}
}
我的JSON那个returns来自APIlink的结构是这样的:
[
{
"Title": "Audio 1",
"Duration": "5 min",
"type": "audio",
"bodyText": "lorem ipsum blah blah audio",
"url": "https://www.silvermansound.com/music/dirty-gertie.mp3"
},
{
"Title": "Video 1",
"Duration": "5 min",
"type": "video",
"bodyText": "lorem ipsum blah blah video",
"url": "https://assets.mixkit.co/videos/preview/mixkit-woman-wearing-a-mask-while-running-40158-large.mp4"
},
{
"Title": "Audio 2",
"Duration": "5 min",
"type": "audio",
"bodyText": "lorem ipsum blah blah audio",
"url": "https://www.silvermansound.com/music/dirty-gertie.mp3"
},
{
"Title": "Video 2",
"Duration": "5 min",
"type": "video",
"bodyText": "lorem ipsum blah blah video",
"url": "https://assets.mixkit.co/videos/preview/mixkit-woman-wearing-a-mask-while-running-40158-large.mp4"
},
{
"Title": "Audio 3",
"Duration": "5 min",
"type": "audio",
"bodyText": "lorem ipsum blah blah audio",
"url": "https://www.silvermansound.com/music/dirty-gertie.mp3"
},
{
"Title": "Video 3",
"Duration": "5 min",
"type": "video",
"bodyText": "lorem ipsum blah blah video",
"url": "https://assets.mixkit.co/videos/preview/mixkit-woman-wearing-a-mask-while-running-40158-large.mp4"
},
]
这是我在 VS 代码调试控制台中遇到的错误:
The argument type 'Future<List<dynamic>> Function()' can't be assigned to the parameter type 'Future<Object?>?'.
红线出现在我试图在 FutureBuilder 中定义我的未来的地方 fetchSectionData
:
return FutureBuilder(
future: fetchSectionData,
builder: (context, snapshot) {
我不确定这个错误是什么意思。有人可以解释一下吗? Future 肯定会返回一个 ,但是我如何将这个列表放入 futurebuilder 中以便我可以对其进行迭代并将数据输出到 gridview 中?
我是 flutter 的新手,来自 javascript 网络背景,通常在 javascript 中,您可以循环遍历数组并以这种方式输出它。我很想在这里这样做,但我知道那是不对的。
当我查阅有关如何从互联网获取数据的 Flutter 文档时,它提到我必须将响应转换为自定义 dart 对象,但我尝试的任何方法似乎都不起作用。
感谢您的帮助!
你必须像这样传递函数
future: fetchSectionData(),
- 在您的 GridView 中最好使用
...
itemCount: snapshot.data.length
...
- List
等于 List it self
Future<List> fetchSectionData() async{
...
- 确定 FutureBuilder 的类型是一个很好的做法
FutureBuilder<List>(
...
试试这个!
return FutureBuilder<List<dynamic>>(
future: fetchSectionData,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return GridView.builder(
itemCount: 12,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300,
crossAxisSpacing: 16.0,
mainAxisSpacing: 18.0,
childAspectRatio: MediaQuery.of(context).size.height / 930,
),
itemBuilder: (BuildContext context, int index) => GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OtherScreen()),
);
},
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 12.0),
height: 144,
),
Text(
'${snapshot.data[index]['Title']}',
),
Text(
'${snapshot.data[index]['Duration'] + ' - ' + snapshot.data[index]['type']}',
),
],
),
),
);
} else {
return Center(
child: CircularProgressIndicator(
color: Colors.black,
),
);
}
},
);
我在尝试使用 Flutter 的 FutureBuilder 从远程 URL 遍历 JSON 对象数组时遇到问题。
我的目标是:
- 从 API 中获取 JSON 数据
- 将数据输出到 2 列网格视图布局中
JSON 数据是一个对象数组(或 dart 中的地图列表),对象具有简单的字符串数据。
我知道我需要构建一个未来来从 API 获取数据并解码 JSON,然后我需要创建一个 FutureBuilder 来将列表数据输出到我的 Gridview Builder .这就是我在下面的代码中尝试做的事情。
import 'dart:convert';
import 'dart:async';
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class HomeSection extends StatefulWidget {
@override
_HomeSectionState createState() => _HomeSectionState();
}
class _HomeSectionState extends State<HomeSection> {
@override
void initState() {
super.initState();
}
Future<List<dynamic>> fetchSectionData() async {
String dataUrl =
'https://www.thisisthejsonapilink.co.uk/fetch-data';
var response = await http.get(Uri.parse(dataUrl));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to get the data');
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: fetchSectionData,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return GridView.builder(
itemCount: 12,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300,
crossAxisSpacing: 16.0,
mainAxisSpacing: 18.0,
childAspectRatio: MediaQuery.of(context).size.height / 930,
),
itemBuilder: (BuildContext context, int index) => GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OtherScreen()),
);
},
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 12.0),
height: 144,
),
Text(
snapshot.data[index].title,
),
Text(
snapshot.data[index].duration + ' - ' + snapshot.data[index].type,
),
],
),
),
);
} else {
return Center(
child: CircularProgressIndicator(
color: Colors.black,
),
);
}
},
);
}
}
我的JSON那个returns来自APIlink的结构是这样的:
[
{
"Title": "Audio 1",
"Duration": "5 min",
"type": "audio",
"bodyText": "lorem ipsum blah blah audio",
"url": "https://www.silvermansound.com/music/dirty-gertie.mp3"
},
{
"Title": "Video 1",
"Duration": "5 min",
"type": "video",
"bodyText": "lorem ipsum blah blah video",
"url": "https://assets.mixkit.co/videos/preview/mixkit-woman-wearing-a-mask-while-running-40158-large.mp4"
},
{
"Title": "Audio 2",
"Duration": "5 min",
"type": "audio",
"bodyText": "lorem ipsum blah blah audio",
"url": "https://www.silvermansound.com/music/dirty-gertie.mp3"
},
{
"Title": "Video 2",
"Duration": "5 min",
"type": "video",
"bodyText": "lorem ipsum blah blah video",
"url": "https://assets.mixkit.co/videos/preview/mixkit-woman-wearing-a-mask-while-running-40158-large.mp4"
},
{
"Title": "Audio 3",
"Duration": "5 min",
"type": "audio",
"bodyText": "lorem ipsum blah blah audio",
"url": "https://www.silvermansound.com/music/dirty-gertie.mp3"
},
{
"Title": "Video 3",
"Duration": "5 min",
"type": "video",
"bodyText": "lorem ipsum blah blah video",
"url": "https://assets.mixkit.co/videos/preview/mixkit-woman-wearing-a-mask-while-running-40158-large.mp4"
},
]
这是我在 VS 代码调试控制台中遇到的错误:
The argument type 'Future<List<dynamic>> Function()' can't be assigned to the parameter type 'Future<Object?>?'.
红线出现在我试图在 FutureBuilder 中定义我的未来的地方 fetchSectionData
:
return FutureBuilder(
future: fetchSectionData,
builder: (context, snapshot) {
我不确定这个错误是什么意思。有人可以解释一下吗? Future 肯定会返回一个 ,但是我如何将这个列表放入 futurebuilder 中以便我可以对其进行迭代并将数据输出到 gridview 中?
我是 flutter 的新手,来自 javascript 网络背景,通常在 javascript 中,您可以循环遍历数组并以这种方式输出它。我很想在这里这样做,但我知道那是不对的。
当我查阅有关如何从互联网获取数据的 Flutter 文档时,它提到我必须将响应转换为自定义 dart 对象,但我尝试的任何方法似乎都不起作用。
感谢您的帮助!
你必须像这样传递函数
future: fetchSectionData(),
- 在您的 GridView 中最好使用
...
itemCount: snapshot.data.length
...
- List
等于 List it self
Future<List> fetchSectionData() async{
...
- 确定 FutureBuilder 的类型是一个很好的做法
FutureBuilder<List>(
...
试试这个!
return FutureBuilder<List<dynamic>>(
future: fetchSectionData,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return GridView.builder(
itemCount: 12,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300,
crossAxisSpacing: 16.0,
mainAxisSpacing: 18.0,
childAspectRatio: MediaQuery.of(context).size.height / 930,
),
itemBuilder: (BuildContext context, int index) => GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OtherScreen()),
);
},
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 12.0),
height: 144,
),
Text(
'${snapshot.data[index]['Title']}',
),
Text(
'${snapshot.data[index]['Duration'] + ' - ' + snapshot.data[index]['type']}',
),
],
),
),
);
} else {
return Center(
child: CircularProgressIndicator(
color: Colors.black,
),
);
}
},
);