【问题标题】:Flutter fetch data from the internetFlutter 从互联网上获取数据
【发布时间】:2020-03-19 01:25:37
【问题描述】:

我正在尝试从 here 获取一些信息,例如 nameavatar_urlstargazers_count描述强>

{
  "total_count": 18689015,
  "incomplete_results": true,
  "items": [
    {
      "id": 215415332,
      "node_id": "MDEwOlJlcG9zaXRvcnkyMTU0MTUzMzI=",
      "name": "HackingNeuralNetworks",
      "full_name": "Kayzaks/HackingNeuralNetworks",
      "private": false,
      "owner": {
        "login": "Kayzaks",
        "id": 11071537,
        "node_id": "MDQ6VXNlcjExMDcxNTM3",
        "avatar_url": "https://avatars1.githubusercontent.com/u/11071537?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/Kayzaks",
        "html_url": "https://github.com/Kayzaks",
        "followers_url": "https://api.github.com/users/Kayzaks/followers",
        "following_url": "https://api.github.com/users/Kayzaks/following{/other_user}",
        "gists_url": "https://api.github.com/users/Kayzaks/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/Kayzaks/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/Kayzaks/subscriptions",
        "organizations_url": "https://api.github.com/users/Kayzaks/orgs",
        "repos_url": "https://api.github.com/users/Kayzaks/repos",
        "events_url": "https://api.github.com/users/Kayzaks/events{/privacy}",
        "received_events_url": "https://api.github.com/users/Kayzaks/received_events",
        "type": "User",
        "site_admin": false
      },
      "html_url": "https://github.com/Kayzaks/HackingNeuralNetworks",
      "description": "A small course on exploiting and defending neural networks",
      "fork": false, 
    ....
    ....

在运行时我收到此消息错误:

type _internalLine HashMap<String , dynamic> is not a subtype of type List<dynamic> in type cast

这是完整的代码:

回购项目:

class RepoItem {
  Owner owner;
  String name;
  String stargazers_count;
  String description;

  RepoItem._({this.owner, this.name, this.stargazers_count, this.description});

  factory RepoItem.fromJson(Map<String, dynamic> json) {
    return new RepoItem._(
        owner: json['owner'],
        name: json['name'],
        stargazers_count: json['stargazers_count'],
        description: json['description']);
  }
}

页面状态:

class _MyHomePageState extends State<MyHomePage> {
  List<RepoItem> list = List();
  var isLoading = false;

  Future<List<RepoItem>> _fetchData() async {
    final response = await http.get(
        "https://api.github.com/search/repositories?q=created:%3E2018-10-22&sort=stars&order=desc");
    list = (json.decode(response.body) as List)
        .map((data) => new RepoItem.fromJson(data.body))
        .toList();
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        child: FutureBuilder(
          future: _fetchData(),
          builder: (BuildContext context, AsyncSnapshot asyncSnapshot) {
            if (asyncSnapshot.hasError) {
              return Container(
                child: Center(
                  child: Text(asyncSnapshot.error.toString()),
                ),
              );
            }
            if (asyncSnapshot.data == null) {
              return Container(
                child: Center(
                  child: Text("Loading ..."),
                ),
              );
            } else {
              return ListView.builder(
                itemCount: asyncSnapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    title: Text(asyncSnapshot.data[index].name),
                    leading: CircleAvatar(
                      backgroundImage: NetworkImage(
                          asyncSnapshot.data[index].owner.avatar_url),
                    ),
                    subtitle: Text(asyncSnapshot.data[index].description),
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: json flutter dart


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    可以用payloadFromJson解析,可以看到Payload类的完整代码

    Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
    ... 
    var items = snapshot.data.items;
    return ListView.builder(
      itemCount: items.length,
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text(items[index].name),
          leading: CircleAvatar(
            backgroundImage:
                NetworkImage(items[index].owner.avatarUrl),
          ),
          subtitle: Text(items[index].description),
        );
      },
    );
    

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    
    // To parse this JSON data, do
    //
    //     final payload = payloadFromJson(jsonString);
    
    import 'dart:convert';
    
    Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
    
    String payloadToJson(Payload data) => json.encode(data.toJson());
    
    class Payload {
      String totalCount;
      bool incompleteResults;
      List<Item> items;
    
      Payload({
        this.totalCount,
        this.incompleteResults,
        this.items,
      });
    
      factory Payload.fromJson(Map<String, dynamic> json) => Payload(
            totalCount: json["total_count"].toString(),
            incompleteResults: json["incomplete_results"],
            items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
          );
    
      Map<String, dynamic> toJson() => {
            "total_count": totalCount,
            "incomplete_results": incompleteResults,
            "items": List<dynamic>.from(items.map((x) => x.toJson())),
          };
    }
    
    class Item {
      String id;
      String nodeId;
      String name;
      String fullName;
      bool private;
      Owner owner;
      String htmlUrl;
      String description;
      bool fork;
      String url;
      String forksUrl;
      String keysUrl;
      String collaboratorsUrl;
      String teamsUrl;
      String hooksUrl;
      String issueEventsUrl;
      String eventsUrl;
      String assigneesUrl;
      String branchesUrl;
      String tagsUrl;
      String blobsUrl;
      String gitTagsUrl;
      String gitRefsUrl;
      String treesUrl;
      String statusesUrl;
      String languagesUrl;
      String stargazersUrl;
      String contributorsUrl;
      String subscribersUrl;
      String subscriptionUrl;
      String commitsUrl;
      String gitCommitsUrl;
      String commentsUrl;
      String issueCommentUrl;
      String contentsUrl;
      String compareUrl;
      String mergesUrl;
      String archiveUrl;
      String downloadsUrl;
      String issuesUrl;
      String pullsUrl;
      String milestonesUrl;
      String notificationsUrl;
      String labelsUrl;
      String releasesUrl;
      String deploymentsUrl;
      DateTime createdAt;
      DateTime updatedAt;
      DateTime pushedAt;
      String gitUrl;
      String sshUrl;
      String cloneUrl;
      String svnUrl;
      String homepage;
      int size;
      int stargazersCount;
      int watchersCount;
      String language;
      bool hasIssues;
      bool hasProjects;
      bool hasDownloads;
      bool hasWiki;
      bool hasPages;
      int forksCount;
      dynamic mirrorUrl;
      bool archived;
      bool disabled;
      int openIssuesCount;
      License license;
      int forks;
      int openIssues;
      int watchers;
      DefaultBranch defaultBranch;
      double score;
    
      Item({
        this.id,
        this.nodeId,
        this.name,
        this.fullName,
        this.private,
        this.owner,
        this.htmlUrl,
        this.description,
        this.fork,
        this.url,
        this.forksUrl,
        this.keysUrl,
        this.collaboratorsUrl,
        this.teamsUrl,
        this.hooksUrl,
        this.issueEventsUrl,
        this.eventsUrl,
        this.assigneesUrl,
        this.branchesUrl,
        this.tagsUrl,
        this.blobsUrl,
        this.gitTagsUrl,
        this.gitRefsUrl,
        this.treesUrl,
        this.statusesUrl,
        this.languagesUrl,
        this.stargazersUrl,
        this.contributorsUrl,
        this.subscribersUrl,
        this.subscriptionUrl,
        this.commitsUrl,
        this.gitCommitsUrl,
        this.commentsUrl,
        this.issueCommentUrl,
        this.contentsUrl,
        this.compareUrl,
        this.mergesUrl,
        this.archiveUrl,
        this.downloadsUrl,
        this.issuesUrl,
        this.pullsUrl,
        this.milestonesUrl,
        this.notificationsUrl,
        this.labelsUrl,
        this.releasesUrl,
        this.deploymentsUrl,
        this.createdAt,
        this.updatedAt,
        this.pushedAt,
        this.gitUrl,
        this.sshUrl,
        this.cloneUrl,
        this.svnUrl,
        this.homepage,
        this.size,
        this.stargazersCount,
        this.watchersCount,
        this.language,
        this.hasIssues,
        this.hasProjects,
        this.hasDownloads,
        this.hasWiki,
        this.hasPages,
        this.forksCount,
        this.mirrorUrl,
        this.archived,
        this.disabled,
        this.openIssuesCount,
        this.license,
        this.forks,
        this.openIssues,
        this.watchers,
        this.defaultBranch,
        this.score,
      });
    
      factory Item.fromJson(Map<String, dynamic> json) => Item(
            id: json["id"].toString(),
            nodeId: json["node_id"],
            name: json["name"],
            fullName: json["full_name"],
            private: json["private"],
            owner: Owner.fromJson(json["owner"]),
            htmlUrl: json["html_url"],
            description: json["description"] == null ? null : json["description"],
            fork: json["fork"],
            url: json["url"],
            forksUrl: json["forks_url"],
            keysUrl: json["keys_url"],
            collaboratorsUrl: json["collaborators_url"],
            teamsUrl: json["teams_url"],
            hooksUrl: json["hooks_url"],
            issueEventsUrl: json["issue_events_url"],
            eventsUrl: json["events_url"],
            assigneesUrl: json["assignees_url"],
            branchesUrl: json["branches_url"],
            tagsUrl: json["tags_url"],
            blobsUrl: json["blobs_url"],
            gitTagsUrl: json["git_tags_url"],
            gitRefsUrl: json["git_refs_url"],
            treesUrl: json["trees_url"],
            statusesUrl: json["statuses_url"],
            languagesUrl: json["languages_url"],
            stargazersUrl: json["stargazers_url"],
            contributorsUrl: json["contributors_url"],
            subscribersUrl: json["subscribers_url"],
            subscriptionUrl: json["subscription_url"],
            commitsUrl: json["commits_url"],
            gitCommitsUrl: json["git_commits_url"],
            commentsUrl: json["comments_url"],
            issueCommentUrl: json["issue_comment_url"],
            contentsUrl: json["contents_url"],
            compareUrl: json["compare_url"],
            mergesUrl: json["merges_url"],
            archiveUrl: json["archive_url"],
            downloadsUrl: json["downloads_url"],
            issuesUrl: json["issues_url"],
            pullsUrl: json["pulls_url"],
            milestonesUrl: json["milestones_url"],
            notificationsUrl: json["notifications_url"],
            labelsUrl: json["labels_url"],
            releasesUrl: json["releases_url"],
            deploymentsUrl: json["deployments_url"],
            createdAt: DateTime.parse(json["created_at"]),
            updatedAt: DateTime.parse(json["updated_at"]),
            pushedAt: DateTime.parse(json["pushed_at"]),
            gitUrl: json["git_url"],
            sshUrl: json["ssh_url"],
            cloneUrl: json["clone_url"],
            svnUrl: json["svn_url"],
            homepage: json["homepage"] == null ? null : json["homepage"],
            size: json["size"],
            stargazersCount: json["stargazers_count"],
            watchersCount: json["watchers_count"],
            language: json["language"] == null ? null : json["language"],
            hasIssues: json["has_issues"],
            hasProjects: json["has_projects"],
            hasDownloads: json["has_downloads"],
            hasWiki: json["has_wiki"],
            hasPages: json["has_pages"],
            forksCount: json["forks_count"],
            mirrorUrl: json["mirror_url"],
            archived: json["archived"],
            disabled: json["disabled"],
            openIssuesCount: json["open_issues_count"],
            license:
                json["license"] == null ? null : License.fromJson(json["license"]),
            forks: json["forks"],
            openIssues: json["open_issues"],
            watchers: json["watchers"],
            defaultBranch: defaultBranchValues.map[json["default_branch"]],
            score: json["score"],
          );
    
      Map<String, dynamic> toJson() => {
            "id": id,
            "node_id": nodeId,
            "name": name,
            "full_name": fullName,
            "private": private,
            "owner": owner.toJson(),
            "html_url": htmlUrl,
            "description": description == null ? null : description,
            "fork": fork,
            "url": url,
            "forks_url": forksUrl,
            "keys_url": keysUrl,
            "collaborators_url": collaboratorsUrl,
            "teams_url": teamsUrl,
            "hooks_url": hooksUrl,
            "issue_events_url": issueEventsUrl,
            "events_url": eventsUrl,
            "assignees_url": assigneesUrl,
            "branches_url": branchesUrl,
            "tags_url": tagsUrl,
            "blobs_url": blobsUrl,
            "git_tags_url": gitTagsUrl,
            "git_refs_url": gitRefsUrl,
            "trees_url": treesUrl,
            "statuses_url": statusesUrl,
            "languages_url": languagesUrl,
            "stargazers_url": stargazersUrl,
            "contributors_url": contributorsUrl,
            "subscribers_url": subscribersUrl,
            "subscription_url": subscriptionUrl,
            "commits_url": commitsUrl,
            "git_commits_url": gitCommitsUrl,
            "comments_url": commentsUrl,
            "issue_comment_url": issueCommentUrl,
            "contents_url": contentsUrl,
            "compare_url": compareUrl,
            "merges_url": mergesUrl,
            "archive_url": archiveUrl,
            "downloads_url": downloadsUrl,
            "issues_url": issuesUrl,
            "pulls_url": pullsUrl,
            "milestones_url": milestonesUrl,
            "notifications_url": notificationsUrl,
            "labels_url": labelsUrl,
            "releases_url": releasesUrl,
            "deployments_url": deploymentsUrl,
            "created_at": createdAt.toIso8601String(),
            "updated_at": updatedAt.toIso8601String(),
            "pushed_at": pushedAt.toIso8601String(),
            "git_url": gitUrl,
            "ssh_url": sshUrl,
            "clone_url": cloneUrl,
            "svn_url": svnUrl,
            "homepage": homepage == null ? null : homepage,
            "size": size,
            "stargazers_count": stargazersCount,
            "watchers_count": watchersCount,
            "language": language == null ? null : language,
            "has_issues": hasIssues,
            "has_projects": hasProjects,
            "has_downloads": hasDownloads,
            "has_wiki": hasWiki,
            "has_pages": hasPages,
            "forks_count": forksCount,
            "mirror_url": mirrorUrl,
            "archived": archived,
            "disabled": disabled,
            "open_issues_count": openIssuesCount,
            "license": license == null ? null : license.toJson(),
            "forks": forks,
            "open_issues": openIssues,
            "watchers": watchers,
            "default_branch": defaultBranchValues.reverse[defaultBranch],
            "score": score,
          };
    }
    
    enum DefaultBranch { MASTER }
    
    final defaultBranchValues = EnumValues({"master": DefaultBranch.MASTER});
    
    class License {
      String key;
      String name;
      String spdxId;
      String url;
      String nodeId;
    
      License({
        this.key,
        this.name,
        this.spdxId,
        this.url,
        this.nodeId,
      });
    
      factory License.fromJson(Map<String, dynamic> json) => License(
            key: json["key"],
            name: json["name"],
            spdxId: json["spdx_id"],
            url: json["url"] == null ? null : json["url"],
            nodeId: json["node_id"],
          );
    
      Map<String, dynamic> toJson() => {
            "key": key,
            "name": name,
            "spdx_id": spdxId,
            "url": url == null ? null : url,
            "node_id": nodeId,
          };
    }
    
    class Owner {
      String login;
      String id;
      String nodeId;
      String avatarUrl;
      String gravatarId;
      String url;
      String htmlUrl;
      String followersUrl;
      String followingUrl;
      String gistsUrl;
      String starredUrl;
      String subscriptionsUrl;
      String organizationsUrl;
      String reposUrl;
      String eventsUrl;
      String receivedEventsUrl;
      Type type;
      bool siteAdmin;
    
      Owner({
        this.login,
        this.id,
        this.nodeId,
        this.avatarUrl,
        this.gravatarId,
        this.url,
        this.htmlUrl,
        this.followersUrl,
        this.followingUrl,
        this.gistsUrl,
        this.starredUrl,
        this.subscriptionsUrl,
        this.organizationsUrl,
        this.reposUrl,
        this.eventsUrl,
        this.receivedEventsUrl,
        this.type,
        this.siteAdmin,
      });
    
      factory Owner.fromJson(Map<String, dynamic> json) => Owner(
            login: json["login"],
            id: json["id"].toString(),
            nodeId: json["node_id"],
            avatarUrl: json["avatar_url"],
            gravatarId: json["gravatar_id"],
            url: json["url"],
            htmlUrl: json["html_url"],
            followersUrl: json["followers_url"],
            followingUrl: json["following_url"],
            gistsUrl: json["gists_url"],
            starredUrl: json["starred_url"],
            subscriptionsUrl: json["subscriptions_url"],
            organizationsUrl: json["organizations_url"],
            reposUrl: json["repos_url"],
            eventsUrl: json["events_url"],
            receivedEventsUrl: json["received_events_url"],
            type: typeValues.map[json["type"]],
            siteAdmin: json["site_admin"],
          );
    
      Map<String, dynamic> toJson() => {
            "login": login,
            "id": id,
            "node_id": nodeId,
            "avatar_url": avatarUrl,
            "gravatar_id": gravatarId,
            "url": url,
            "html_url": htmlUrl,
            "followers_url": followersUrl,
            "following_url": followingUrl,
            "gists_url": gistsUrl,
            "starred_url": starredUrl,
            "subscriptions_url": subscriptionsUrl,
            "organizations_url": organizationsUrl,
            "repos_url": reposUrl,
            "events_url": eventsUrl,
            "received_events_url": receivedEventsUrl,
            "type": typeValues.reverse[type],
            "site_admin": siteAdmin,
          };
    }
    
    enum Type { USER, ORGANIZATION }
    
    final typeValues =
        EnumValues({"Organization": Type.ORGANIZATION, "User": Type.USER});
    
    class EnumValues<T> {
      Map<String, T> map;
      Map<T, String> reverseMap;
    
      EnumValues(this.map);
    
      Map<T, String> get reverse {
        if (reverseMap == null) {
          reverseMap = map.map((k, v) => new MapEntry(v, k));
        }
        return reverseMap;
      }
    }
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      static final String URL = "https://corona.lmao.ninja/countries";
      Future _future;
    
      Future<Payload> _fetchData() async {
        final response = await http.get(
            "https://api.github.com/search/repositories?q=created:%3E2018-10-22&sort=stars&order=desc");
        var list = payloadFromJson(response.body);
        return list;
      }
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        _future = _fetchData();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: FutureBuilder<Payload>(
                future: _future,
                builder: (BuildContext context, AsyncSnapshot<Payload> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.none:
                      return Text('Input a URL to start');
                    case ConnectionState.waiting:
                      return Center(child: CircularProgressIndicator());
                    case ConnectionState.active:
                      return Text('');
                    case ConnectionState.done:
                      if (snapshot.hasError) {
                        return Text(
                          '${snapshot.error}',
                          style: TextStyle(color: Colors.red),
                        );
                      } else {
                        var items = snapshot.data.items;
                        return ListView.builder(
                          itemCount: items.length,
                          itemBuilder: (BuildContext context, int index) {
                            return ListTile(
                              title: Text(items[index].name),
                              leading: CircleAvatar(
                                backgroundImage:
                                    NetworkImage(items[index].owner.avatarUrl),
                              ),
                              subtitle: Text(items[index].description),
                            );
                          },
                        );
                      }
                  }
                }));
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 2013-06-14
      • 2020-04-24
      • 2016-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多