如何将JSON响应放入窗口小部件中

时间:2020-04-01 08:24:12

标签: flutter

我想使用小部件中显示的响应数据。我将数据发布到我的API,然后得到返回结果。

我的 response.body 是这样的:

{
    "responses": [
        {
            "Contents": {
                "Images": [
                    {"url":"https:URL"}, 
                    {"url":"https:URL"}, 
                ],
                "Ages": [
                    {"age":"33"},
                    {"age":"34"}, 
                ],
                "Labels":[
                    {"label":"game"}
                ]
            }
        }
    ]
}

我的问题是如何获取“ 图片”,“ 年龄”和“ 标签”的详细信息?我想使用这些细节并放入我的小部件中。我能知道怎么做吗?

2 个答案:

答案 0 :(得分:1)

在Dart中制作完整的模型来解码JSON并不是强制性的。 您可以轻松做到:

// Requires import
import 'dart:convert';

// Do like this
var data = jsonDecode(jsonString);

现在数据将自动充当地图。

例如,如果要访问所提供的JSON示例中的标签,则只需执行以下操作:

data['responses'][0]['Contents']['Labels'][0]['label'].toString();

谈到实际部分, 您需要根据需要调整窗口小部件的形状。

创建一个满足您需求的无状态或StatefulWidget,并开始布局设计。

根据您发布的JSON示例,您需要显示图像列表。因此,您可能会根据URL生成窗口小部件的列表,并在构建方法中将该列表提供给GridView。

检查我做的这个例子:DartPad - JSON Widget example

编辑:

我使用了您发布的确切JSON响应。它不会给我任何错误。

class _MyWidgetState extends State<MyWidget> {
  final String mJson = '''
    {
    "responses": [
        {
            "Contents": {
                "Images": [
                    {"url":"https:URL"}, 
                    {"url":"https:URL"}
                ],
                "Ages": [
                    {"age":"33"},
                    {"age":"34"}
                ],
                "Labels":[
                    {"label":"game"}
                ]
            }
        }
    ]
}
  ''';

  bool _loading = false;
  List<String> _infos = [];

  Widget _loadingBar() {
    return SizedBox.fromSize(
        size: Size.fromRadius(30),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(
              Colors.white,
            ),
          ),
        ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('MY APPS'), actions: <Widget>[
          _loading
              ? _loadingBar()
              : IconButton(
                  icon: Icon(Icons.send),
                  onPressed: () => {
                        submit(context)
                            .then((res) => setState(() => _loading = false))
                      }),
        ]),
        body: SingleChildScrollView(
          padding: const EdgeInsets.all(16.0),
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: List.generate(_infos.length, (i) => Text(_infos[i]))),
        ));
  }

  Future<void> submit(BuildContext context) async {
    setState(() => _loading = true);
    await Future.delayed(const Duration(seconds: 3));
    var data = jsonDecode(mJson);
    print(data);
    _infos.add(data['responses'][0].toString());
    _infos.add(data['responses'][0]['Contents'].toString());
    _infos.add(data['responses'][0]['Contents']['Images'][0]['url'].toString());
    _infos.add(data['responses'][0]['Contents']['Ages'][0]['age'].toString());
  }
}

注意:稍后发布的代码不起作用,因为您已在StatelessWidget类中声明了非最终变量,并且还使用了setState。另外,在您的Future Submit(BuildContext上下文)中,您应该使用jsonDecode(res)而不是demoJson。未分配demoJson。请参阅我发布的示例。我将其更改为有状态的小部件。我可以轻松访问您提供的JSON示例中的任何字段。不过,您的JSON示例有点错误,它有额外的',',在解码时可能会出错。

Updated

答案 1 :(得分:0)

只需检查以下我所做的示例: Follwing是您提供的我已在本地解析的json文件。

{
    "responses": [{
        "Contents": {
            "Images": [{
                    "url": "https:URL"
                },
                {
                    "url": "https:URL"
                }
            ],
            "Ages": [{
                    "age": "33"
                },
                {
                    "age": "34"
                }
            ],
            "Labels": [{
                    "age": "33"
                }

            ]
        }
    }]
}

为json文件创建的模型类:

// To parse this JSON data, do
//
//     final response = responseFromJson(jsonString);

import 'dart:convert';

Response responseFromJson(String str) => Response.fromJson(json.decode(str));

String responseToJson(Response data) => json.encode(data.toJson());

class Response {
    List<ResponseElement> responses;

    Response({
        this.responses,
    });

    factory Response.fromJson(Map<String, dynamic> json) => Response(
        responses: List<ResponseElement>.from(json["responses"].map((x) => ResponseElement.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "responses": List<dynamic>.from(responses.map((x) => x.toJson())),
    };
}

class ResponseElement {
    Contents contents;

    ResponseElement({
        this.contents,
    });

    factory ResponseElement.fromJson(Map<String, dynamic> json) => ResponseElement(
        contents: Contents.fromJson(json["Contents"]),
    );

    Map<String, dynamic> toJson() => {
        "Contents": contents.toJson(),
    };
}

class Contents {
    List<Image1> images;
    List<Age> ages;
    List<Age> labels;

    Contents({
        this.images,
        this.ages,
        this.labels,
    });

    factory Contents.fromJson(Map<String, dynamic> json) => Contents(
        images: List<Image1>.from(json["Images"].map((x) => Image1.fromJson(x))),
        ages: List<Age>.from(json["Ages"].map((x) => Age.fromJson(x))),
        labels: List<Age>.from(json["Labels"].map((x) => Age.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "Images": List<dynamic>.from(images.map((x) => x.toJson())),
        "Ages": List<dynamic>.from(ages.map((x) => x.toJson())),
        "Labels": List<dynamic>.from(labels.map((x) => x.toJson())),
    };
}

class Age {
    String age;

    Age({
        this.age,
    });

    factory Age.fromJson(Map<String, dynamic> json) => Age(
        age: json["age"],
    );

    Map<String, dynamic> toJson() => {
        "age": age,
    };
}

class Image1 {
    String url;

    Image1({
        this.url,
    });

    factory Image1.fromJson(Map<String, dynamic> json) => Image1(
        url: json["url"],
    );

    Map<String, dynamic> toJson() => {
        "url": url,
    };
}

这是您获取并显示数据的主UI文件,我已经在列表视图中显示了数据。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sample_project_for_api/model.dart';

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

class _HomePageState extends State<HomePage> {
  bool isLoading = false;
  List<Age> ages = List();
  List<Age> labels = List();
  List<Image1> image = List();

  // here i have taken the  json locally which you posted on stack
  Future<String> loadFromAssets() async {
    return await rootBundle.loadString('json/parse.json');
  }

  @override
  void initState() {
    super.initState();
    givenFunction();
  }

  Future givenFunction() async {
    setState(() {
      isLoading = true;
    });

    //http.Response response = await http.post(url, body: json.encode(data));
    // you can make the http call above just uncomment is and comment the below line
    String jsonString = await loadFromAssets();
    // Here you can just replace down your response.body with jsonString
    final response = responseFromJson(jsonString);
    print(response.responses[0].contents.ages[0].age);
    //ages =response.responses[0].contents.
    for (int i = 0; i < response.responses[0].contents.ages.length; i++) {
      ages.add(response.responses[0].contents.ages[i]);
    }

    for (int i = 0; i < response.responses[0].contents.images.length; i++) {
      image.add(response.responses[0].contents.images[i]);
    }
    for (int i = 0; i < response.responses[0].contents.labels.length; i++) {
      labels.add(response.responses[0].contents.labels[i]);
    }
    setState(() {
      isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: isLoading
              ? CircularProgressIndicator()
              : SafeArea(
                  child: Container(
                    child: Column(
                      children: <Widget>[
                        Container(
                          width: 400,
                          height: 100,
                          child: ListView.builder(
                            scrollDirection: Axis.horizontal,
                            itemCount: ages.length,
                            itemBuilder: (BuildContext context, int index) {
                              return Container(
                                width: 100,
                                height: 100,
                                child: Card(
                                  elevation: 10,
                                  child: Center(child: Text(ages[index].age)),
                                ),
                              );
                            },
                          ),
                        ),
                        Container(
                          width: 500,
                          height: 200,
                          child: ListView.builder(
                            scrollDirection: Axis.horizontal,
                            itemCount: image.length,
                            itemBuilder: (BuildContext context, int index) {
                              return Container(
                                width: 100,
                                height: 100,
                                child: Card(
                                  elevation: 10,
                                  child: Center(child: Text(image[index].url)),
                                ),
                              );
                            },
                          ),
                        ),
                        Container(
                          width: 500,
                          height: 200,
                          child: ListView.builder(
                            scrollDirection: Axis.horizontal,
                            itemCount: labels.length,
                            itemBuilder: (BuildContext context, int index) {
                              return Container(
                                width: 100,
                                height: 100,
                                child: Card(
                                  elevation: 10,
                                  child: Center(child: Text(labels[index].age)),
                                ),
                              );
                            },
                          ),
                        )
                      ],
                    ),
                  ),
                )),
    );
  }
}

void main() {
  runApp(HomePage());
}


仅拍摄了一个屏幕截图: enter image description here

只需检查一下,让我知道。