在null

时间:2018-09-18 09:28:47

标签: dart flutter

我制作了一个随机的json,其中列出了他们购买的人和事物的列表,这是内容:

random.json

{
  "people": [
    {
      "name": "person1",
      "id": "1",
      "thingsbought": {
        "fish": {
          "price" : "10"
        },
        "chicken": {
          "price" : "5"
        },
        "vegetables": {
          "price" : "15"
        },
        "drinks": {
          "price" : "10"
        }
      }
    },
    {
      "name": "person2",
      "id": "2",
      "thingsbought": {
        "fish": {
          "price" : "10"
        },
        "vegetables": {
          "price" : "15"
        }
      }
    },    
    {
      "name": "person3",
      "id": "3",
      "thingsbought": {
        "chicken": {
          "price" : "5"
        },
        "vegetables": {
          "price" : "15"
        },
        "drinks": {
          "price" : "10"
        }
      }
    }
  ]
}

该应用程序包含两个页面。第一页显示带有ID的名称列表,下一页根据JSON中的索引号列出他们购买的商品。

我对第一页没有问题。这是出于上下文目的的屏幕截图。

首页 First Page

这是单击任何人后的下一页

ThingsBought.dart(第二页)

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

final String url = "http://crm.emastpa.com.my/random.json";

Future<String> loadThings() async {
  var res = await http.get(
      Uri.encodeFull(url),
      headers: {"Accept": "application/json"});
  return res.body;
}

class ThingsBought extends StatefulWidget {

  ThingsBought({Key key, this.index, this.name}) : super(key:key);

  final int index;
  final String name;

  @override
  _ThingsBoughtState createState() => _ThingsBoughtState();
}

class _ThingsBoughtState extends State<ThingsBought> {

  makeCard(String title, String price){
    return new Card(
      child: new ExpansionTile(
          title: new Text(title),
          children: <Widget>[
            new ListTile(
              title: new Text("Price"),
              trailing: new Text(price),
            )
          ]),
    );
  }

  @override
  Widget build(BuildContext context) {

    Widget body = new Container(
      child: new FutureBuilder(
          future: loadThings(),
          builder: (context, snapshot){
            if(snapshot.hasData){

              List<Widget> widgets = [];

              Map decoded = json.decode(snapshot.data)["people"][widget.index]["thingsbought"];


              var fishprice = decoded["fish"]["price"];


              var chickenprice = decoded["chicken"]["price"];


              var vegetableprice = decoded["vegetables"]["price"];


              var drinkprice = decoded["drinks"]["price"];


              if(decoded.containsKey("fish")){
                widgets.add(makeCard("Fish", fishprice));
              }else{
                return new Container();
              }

              if(decoded.containsKey("chicken")){
                widgets.add(makeCard("Chicken", chickenprice));
              }else{
                return new Container();
              }

              if(decoded.containsKey("vegetables")){
                widgets.add(makeCard("Vegetables", vegetableprice));
              }else{
                return new Container();
              }

              if(decoded.containsKey("drinks")){
                widgets.add(makeCard("Drinks", drinkprice));
              }else{
                return new Container();
              }


              return new Column(
                children: widgets,
              );
            }else{
              return new Center(
                child: new CircularProgressIndicator(),
              );
            }
          }
      ),
    );

    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Things Bought"),
      ),
      body: new SingleChildScrollView(
        child: body,
      ),
    );
  }
}

这里的问题是,每当我单击作为第一个索引的person1时,结果就很好。

效果很好的第一个索引的屏幕截图

FIRST INDEX

但是单击其他人将导致错误,如下面的屏幕截图所示。

具有错误的第二个索引和第三个索引的屏幕截图

Things Bought

我肯定知道第一个索引有效,因为所有键都存在。但是我不知道为什么即使我将return new Container();用作else语句也无法读取其他语句。

有人可以向我解释我做错了什么以及如何更正我的代码吗?

2 个答案:

答案 0 :(得分:1)

在您的JSON中,未设置fishchickenvegetablesdrinks。 以下代码不起作用。 decoded["fish"]可以为空。

var fishprice = decoded["fish"]["price"];
var chickenprice = decoded["chicken"]["price"];
var vegetableprice = decoded["vegetables"]["price"];
var drinkprice = decoded["drinks"]["price"];

答案 1 :(得分:0)

对于任何遇到此问题的人,我都找到了适合我的解决方案。

当在if语句之外声明调用键所需的变量时,会发生问题

这很错误

          var fishprice = decoded["fish"]["price"];


          var chickenprice = decoded["chicken"]["price"];


          var vegetableprice = decoded["vegetables"]["price"];


          var drinkprice = decoded["drinks"]["price"];


          if(decoded.containsKey("fish")){
            widgets.add(makeCard("Fish", fishprice));
          }else{
            return new Container();
          }

          if(decoded.containsKey("chicken")){
            widgets.add(makeCard("Chicken", chickenprice));
          }else{
            return new Container();
          }

          if(decoded.containsKey("vegetables")){
            widgets.add(makeCard("Vegetables", vegetableprice));
          }else{
            return new Container();
          }

          if(decoded.containsKey("drinks")){
            widgets.add(makeCard("Drinks", drinkprice));
          }else{
            return new Container();
          }

这是正确的版本

              //Declare the variables inside the if statement and remove the return from new Container()
              if(decoded.containsKey("fish")){
                var fishprice = decoded["fish"]["price"];
                widgets.add(makeCard("Fish", fishprice));
              }else{
                new Container();
              }

              if(decoded.containsKey("chicken")){
                var chickenprice = decoded["chicken"]["price"];
                widgets.add(makeCard("Chicken", chickenprice));
              }else{
                new Container();
              }

              if(decoded.containsKey("vegetables")){
                var vegetableprice = decoded["vegetables"]["price"];
                widgets.add(makeCard("Vegetables", vegetableprice));
              }else{
                new Container();
              }

              if(decoded.containsKey("drinks")){
                var drinkprice = decoded["drinks"]["price"];
                widgets.add(makeCard("Drinks", drinkprice));
              }else{
                new Container();
              }

因此,此更改的原因是:在if语句之外声明变量将已经从json调用,这就是发生错误的原因。因此,正确的方法是在if语句确认密钥存在之后调用if。