【问题标题】:How to put the json response in widget flutter如何将 json 响应放入小部件颤动中
【发布时间】:2020-07-12 22:37:10
【问题描述】:

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

我的response.body是这样的:

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

我的问题是如何获取“Images”、“Ages”和“Labels”详细信息?我想使用这些细节并放入我的小部件中。我能知道怎么做吗?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    在 Dart 中制作完整模型来解码 JSON 不是强制性的。 你可以这样做:

    // Requires import
    import 'dart:convert';
    
    // Do like this
    var data = jsonDecode(jsonString);
    

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

    例如,如果您想访问您提供的 JSON 示例中的标签,您可以简单地这样做:

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

    进入实际部分, 你需要根据自己的需要来塑造你的小部件。

    根据您的需要创建一个 Stateless 或 StatefulWidget 并开始布局设计。

    根据您发布的 JSON 示例,您需要显示图像列表。因此,您可能会根据 URL 生成一个 Widget 列表,并将该列表提供给您的构建方法中的 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。此外,在您的未来提交(BuildContext 上下文)中,您应该使用 jsonDecode(res) 而不是 demoJson。未分配 demoJson。请参阅我发布的示例。我将其更改为有状态的小部件。我可以毫无问题地访问您提供的 JSON 示例中的任何字段。不过,您的 JSON 示例有点错误,它有额外的“,”,可能会在解码时出错。

    【讨论】:

    • 感谢您的帮助。我什么时候需要做模型代码?当我不需要?我认为非常需要做模型代码。
    • 这完全取决于你。如果您愿意,可以使用模型。唯一会改变的是在模型的情况下访问数据的方式。例如,假设 personData 是我的 dartpad 示例中的类模型。我必须以 personData.name 的形式访问名称,而不是 personData['name'] 等等。所以我的文本小部件会有 ${personData.name} 等等。
    • 哦,我明白了,谢谢你的帮助
    • 对不起先生,为什么当我使用我的响应数据时会显示这个错误? type '_InternalLinkedHashMap' 不是'Map>>' 类型的子类型 我已经编辑了我的问题
    • 您是否在某处对 var 数据进行类型转换?
    【解决方案2】:

    只需检查我制作的以下示例: 以下是你提供的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());
    }
    
    
    

    刚刚截屏:

    请检查并告诉我。

    【讨论】:

    • 效果很好,点个赞,对别人有帮助
    猜你喜欢
    • 2021-08-30
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2020-05-26
    相关资源
    最近更新 更多