json - Flutter中制作卡片复杂的API响应如何处理?

标签 json dart flutter

我是 Flutter 的新手,现在正在开发一个列出餐馆的应用程序。 我有一个返回 JSON 数据的 API 端点。这是:https://node.coredes.in/restaurants .

我已经完成了布局。但我不知道如何处理 JSON 数据。我已经尝试通过从网上获得的示例来执行此操作。

我想知道如何使用这些字段 - doc.name、doc.image_gallery[0]、doc.location.locality、doc.friday.closing_at.hour、doc.friday.closing_at.minute,制作一个卡片列表?

谁能帮我提供一个示例代码?

最佳答案

下面是一个示例代码,展示了如何在 JSON 文件中获取餐馆名称:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'dart:async';

void main() {
  runApp(new MaterialApp(
    home: new HomePage(),
  ));
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String url = "https://node.coredes.in/restaurants/";
  List data;

  /*onCreate*/
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    getJSONData(); //method
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(title: Text("my JSON app")),
      body: new ListView.builder(
        // itemCount: 1,
        //itemCount: data==null ? 0 :data.length ,
        itemCount: data == null ? 0 : data.length,

        itemBuilder: (BuildContext context, int index) {
          return new Container(
            child: new Center(
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  new Card(
                    child: new Container(
                      child: new Text(data[index]['name'] ?? ''),
                      padding: EdgeInsets.all(20),
                    ),
                  )
                ],
              ),
            ),
          );
        },
      ),
    );
  }

  /*method*/ //RT is Future<String>
  Future<String> getJSONData() async {
    var response = await http
        .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    print(response.body);
    debugPrint(response.body);

    setState(() {
      var convertDataToJson = json.decode(response.body);
      data = convertDataToJson['doc'];
    });

    return "Success";
  }
}

您还可以使用 data[index]['name']。例如,如果你想要城市,你可以做类似 data[index]['location']['city'] 的事情。

所以你说的类模型,是为了让你的代码易于理解,快速复用。您的 JSON 文件包含复杂的嵌入式数据,访问这些数据有点困难。因此,使用类模型将非常有助于轻松获得,无论您希望从中获得什么值(value)。让我用一个具体的例子来告诉你,要知道餐厅什么时候开门和关门,你需要遵循这个层次结构 doc => opening_times => Sunday => opening_at 和关闭时间。所以让我们把它翻译成我们的 flutter 代码,如果我们只想获取 hour 值,它将像 data[index]['opening_time']['Sunday']['opening_at ']['hour']minute 值相同,其余所有值相同。在这个层级中我们并没有花那么长时间就走到了尽头,但是你可以自由想象在一个非常大的层级中,会是怎样的情况。让我们回到我们的案例,现在让我们采用相同的示例并尝试使用,就像您所说的那样,使用类模型而不是硬编码的 JSON 属性。让我们为 Restaurant 编写一个模型类。

class Restaurant {
  String name;
  String city;
  String day;
  bool isOpen;
  int hourOpen;
  int minuteOpen;
// ..
// ..
// The rest of your wanted attributs
  Restaurant(
      {this.name,
      this.city,
      this.day,
      this.isOpen,
      this.hourOpen,
      this.minuteOpen});
}

之后,我们将编写一个方法,其主要目标是填充我们的 restaurants 变量。

  Future<String> getRestaurants() async {
    var response = await http
        .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    var convertDataToJson = json.decode(response.body);
    data = convertDataToJson['doc'];
    List tempRestaurants = new List();
    data.forEach((restaurant) => {
          tempRestaurants.add(new Restaurant(
              name: restaurant['name'],
              city: restaurant['location']['city'],
              day: 'Sunday',
              isOpen: restaurant['opening_times']['Sunday']['is_open_today'],
              hourOpen: restaurant['opening_times']['Sunday']['opening_at']
                  ['hour'],
              minuteOpen: restaurant['opening_times']['Sunday']['opening_at']
                  ['minute'])),
        });

    setState(() {
      this.restaurants = tempRestaurants;
    });
  }

这是我们在编写模型后获取数据的方式。

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(title: Text("my JSON app")),
      body: new ListView.builder(
        itemCount: restaurants == null ? 0 : restaurants.length,
        itemBuilder: (BuildContext context, int index) {
          return new Container(
            child: new Center(
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  new Card(
                    child: new Container(
                      child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text("Name: ${restaurants[index].name}"),
                            Text("City: ${restaurants[index].city}"),
                            Text("Day: ${restaurants[index].day}"),
                            Text("IsOpen: ${restaurants[index].isOpen}"),
                            Text(
                                "Time: ${restaurants[index].hourOpen}:${restaurants[index].minuteOpen}"),
                          ]),
                      padding: EdgeInsets.all(20),
                    ),
                  )
                ],
              ),
            ),
          );
        },
      ),
    );
  }

PS:在这个例子中,我只取了每个餐厅实例中的 Sunday 值,这样我就可以向您展示访问数据变得多么容易。但是你可以为它创建一个类模型,比方说 RestaurantDay,并具有 dayNamehourOpenminuteOpen 等属性>...然后,您可以将它与我们获取数据的逻辑链接起来。

关于json - Flutter中制作卡片复杂的API响应如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56040221/

相关文章:

ios - 在 Firebase 上创建用户时设置值 - Swift

java - Spring和RESTfull ConcurrentModel不支持null属性值

java - Android if/else无法停止发布JSON

dart - 使用 Dart 解析 URI 以提取查询参数

firebase - 如果我只使用 flutter web(没有 android 或 ios 应用程序),我是否还应该在 index.html 和 main.dart 中初始化 firebase 应用程序两次?

javascript - Lodash 和 Angular : Transform JSON object into view model

dart - 在dart中将元素滚动到底部

datetime - 在 Flutter (Dart) 中将字符串解析为 DateTime

使用 .aar 模块的 Flutter 插件在示例应用程序中构建和运行良好,但无法在其他应用程序中构建

dart - 我们可以使用 Flutter 或 Dart 制作 Web 应用程序或网站吗