使用 Flutter FutureBuilder 迭代 JSON 中的对象数组

Iterating over an array of objects in JSON with Flutter FutureBuilder

我在尝试使用 Flutter 的 FutureBuilder 从远程 URL 遍历 JSON 对象数组时遇到问题。

我的目标是:

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,
            ),
          );
        }
      },
    );