简体   繁体   English

Flutter 在 ListView 中加载 json 总是返回空数据

[英]Flutter load json in ListView return always empty data

I' m trying to build a simple app for viewing json data.我正在尝试构建一个简单的应用程序来查看 json 数据。 I started with the example on flutter website: https://flutter.dev/docs/cookbook/networking/fetch-data我从 flutter 网站上的示例开始: https://flutter.dev/docs/cookbook/networking/fetch-data

This is working.这是有效的。

Now I' m trying to load a List of comments from: https://jsonplaceholder.typicode.com/comments/现在我正在尝试从以下位置加载评论列表: https://jsonplaceholder.typicode.com/comments/

When I run the app I see only the circle loaded from CircularProgressIndicator.当我运行应用程序时,我只看到从 CircularProgressIndicator 加载的圆圈。 Why?为什么? I'm not able to get the data but I don' t understand why, can you help me?我无法获取数据,但我不明白为什么,你能帮帮我吗? Here is the code:这是代码:

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

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter json test',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter json test'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  Future<List<Comment>> _getComments() async {

    var data = await http.get("https://jsonplaceholder.typicode.com/comments/");
    List<Comment> comments = [];

    if(data.statusCode==200) {
      var jsonData = json.decode(data.body);

      for (var d in jsonData) {
        Comment comment = Comment(
            d["postId"],d["id"], d["name"], d["email"], d["body"]);

        comments.add(comment);
      }

      print(comments.length.toString());

      return comments;
    }
    else {
      throw Exception('Failed to load album');
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: Container(
        child: FutureBuilder(
          future: _getComments(),
          builder: (BuildContext context, AsyncSnapshot snapshot){
            if(snapshot.hasData){
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    title: Text( snapshot.data[index]['name']),
                    subtitle: Text(snapshot.data[index]['email']),
                    onTap: (){
                      Navigator.push(context,
                          new MaterialPageRoute(builder: (context) => DetailPage(snapshot.data[index]))
                      );
                    },
                  );
                },
              );
            } else {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        ),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {

  final Comment comment;

  DetailPage(this.comment);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(comment.name),
        )
    );
  }
}


class Comment {
  final int postId;
  final String id;
  final String name;
  final String email;
  final String body;

  Comment(this.postId, this.id, this.name, this.email, this.body);

}

Can you give me any advice?你能给我什么建议吗? Thank you!谢谢!

You are returning Comment instances not Map instances so you should use the dot accessor.您正在返回Comment实例而不是Map实例,因此您应该使用点访问器。 I'm sure if you check your console, you might see the error.我确定如果您检查控制台,您可能会看到错误。

ListView.builder(
  itemCount: snapshot.data.length,
  itemBuilder: (BuildContext context, int index) {
    return ListTile(
      title: Text( snapshot.data[index].name), // Change here
      subtitle: Text(snapshot.data[index].email), // Change here
      onTap: () {
        Navigator.push(context,
         new MaterialPageRoute(builder: (context) => 
            DetailPage(snapshot.data[index]))
         );
      },
    );
  }
)

First, you need to convert your JSON data into Map<String, dynamic> and then parsed it into List .首先,您需要将 JSON 数据转换为Map<String, dynamic>然后将其解析为List By looking at your code you have only converted data into List so the Type int is not a subtype of String error occurred .通过查看您的code ,您只将数据转换为 List,因此Type int is not a subtype of String error occurred Also, you have not added an error statement into your FutureBuilder so you have to face difficulties to read error so please do check my answer此外,您还没有在 FutureBuilder 中添加错误语句,因此您必须面对阅读错误的困难,所以请检查我的答案

You need to call this CommentPage from your main.dart file您需要从main.dart文件中调用此CommentPage

class CommentPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _homePage();
  }
}

class _homePage extends State<CommentPage> {
  Future<List<CommentModel>> getPostData() async {
    var url = "https://jsonplaceholder.typicode.com/comments";
    final responce = await http.get(url);
    final parsed = json.decode(responce.body).cast<Map<String, dynamic>>();
    return parsed.map<CommentModel>((json) {
      return CommentModel.fromJson(json);
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: Container(
        child: FutureBuilder<List<CommentModel>>(
          future: getPostData(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, int index) {
                  return ListTile(
                      title: Text(snapshot.data[index].name),
                      subtitle: Text(snapshot.data[index].email));
                },
              );
            } else if (snapshot.hasError) {
              return Center(
                child: Text(snapshot.error.toString()),
              );
            }
            return Center(
              child: CircularProgressIndicator(),
            );
          },
        ),
      ),
    );
  }
}

And here is my model class.这是我的model class。 I created this by using this online tool.我使用这个在线工具创建了这个。

class CommentModel {
  CommentModel({
    this.postId,
    this.id,
    this.name,
    this.email,
    this.body,
  });

  int postId;
  int id;
  String name;
  String email;
  String body;

  factory CommentModel.fromJson(Map<String, dynamic> json) => CommentModel(
    postId: json["postId"],
    id: json["id"],
    name: json["name"],
    email: json["email"],
    body: json["body"],
  );

  Map<String, dynamic> toJson() => {
    "postId": postId,
    "id": id,
    "name": name,
    "email": email,
    "body": body,
  };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM