如何在抖动中解析复杂的Json值?

时间:2020-09-01 13:27:11

标签: json flutter dart

我有一个JSON,它是简单结构和复杂结构的组合。无论如何,您都可以看一下。我想要的就是获取“ playlist_url”:值并在列表视图构建器中显示它。解析我可以做的2个文本值。但是url部分是我无法解析的地方

JSON结构(太长了,这就是我给的链接):https://docs.google.com/document/d/1saJN3MQvG55M1ipf42-65Etowi_kW80gkrosU6vBb5o/edit?usp=sharing

PODO文件:

// To parse this JSON data, do
//
//     final homePage = homePageFromJson(jsonString);

import 'dart:convert';

HomePage homePageFromJson(String str) => HomePage.fromJson(json.decode(str));

String homePageToJson(HomePage data) => json.encode(data.toJson());

class HomePage {
  HomePage({
    this.series,
    this.homeBanners,
    this.liveChannels,
    this.publishers,
    this.musicCategories,
    this.musicPlaylists,
    this.movies,
  });

  List<HomeBanner> series;
  List<HomeBanner> homeBanners;
  List<LiveChannel> liveChannels;
  List<Publisher> publishers;
  List<Music> musicCategories;
  Music musicPlaylists;
  List<HomeBanner> movies;

  factory HomePage.fromJson(Map<String, dynamic> json) => HomePage(
        series: List<HomeBanner>.from(
            json["series"].map((x) => HomeBanner.fromJson(x))),
        homeBanners: List<HomeBanner>.from(
            json["home_banners"].map((x) => HomeBanner.fromJson(x))),
        liveChannels: List<LiveChannel>.from(
            json["live_channels"].map((x) => LiveChannel.fromJson(x))),
        publishers: List<Publisher>.from(
            json["publishers"].map((x) => Publisher.fromJson(x))),
        musicCategories: List<Music>.from(
            json["music_categories"].map((x) => Music.fromJson(x))),
        musicPlaylists: Music.fromJson(json["music_playlists"]),
        movies: List<HomeBanner>.from(
            json["movies"].map((x) => HomeBanner.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "series": List<dynamic>.from(series.map((x) => x.toJson())),
        "home_banners": List<dynamic>.from(homeBanners.map((x) => x.toJson())),
        "live_channels":
            List<dynamic>.from(liveChannels.map((x) => x.toJson())),
        "publishers": List<dynamic>.from(publishers.map((x) => x.toJson())),
        "music_categories":
            List<dynamic>.from(musicCategories.map((x) => x.toJson())),
        "music_playlists": musicPlaylists.toJson(),
        "movies": List<dynamic>.from(movies.map((x) => x.toJson())),
      };
}

class HomeBanner {
  HomeBanner({
    this.movieId,
    this.title,
    this.tags,
    this.genres,
    this.thumbnail,
    this.posterLink,
    this.platform,
    this.worldwide,
    this.createdAt,
    this.seriesId,
  });

  String movieId;
  String title;
  List<String> tags;
  List<String> genres;
  List<String> thumbnail;
  String posterLink;
  Platform platform;
  double worldwide;
  DateTime createdAt;
  String seriesId;

  factory HomeBanner.fromJson(Map<String, dynamic> json) => HomeBanner(
        movieId: json["movie_id"] == null ? null : json["movie_id"],
        title: json["title"],
        tags: List<String>.from(json["tags"].map((x) => x)),
        genres: List<String>.from(json["genres"].map((x) => x)),
        thumbnail: List<String>.from(json["thumbnail"].map((x) => x)),
        posterLink: json["poster_link"],
        platform: platformValues.map[json["platform"]],
        worldwide: json["WORLDWIDE"],
        createdAt: DateTime.parse(json["createdAt"]),
        seriesId: json["series_id"] == null ? null : json["series_id"],
      );

  Map<String, dynamic> toJson() => {
        "movie_id": movieId == null ? null : movieId,
        "title": title,
        "tags": List<dynamic>.from(tags.map((x) => x)),
        "genres": List<dynamic>.from(genres.map((x) => x)),
        "thumbnail": List<dynamic>.from(thumbnail.map((x) => x)),
        "poster_link": posterLink,
        "platform": platformValues.reverse[platform],
        "WORLDWIDE": worldwide,
        "createdAt": createdAt.toIso8601String(),
        "series_id": seriesId == null ? null : seriesId,
      };
}

enum Platform { YOUTUBE, DISCOVERYPLUS }

final platformValues = EnumValues(
    {"discoveryplus": Platform.DISCOVERYPLUS, "youtube": Platform.YOUTUBE});

class LiveChannel {
  LiveChannel({
    this.keyId,
    this.postContent,
    this.publisherId,
    this.publisherName,
    this.publisherProfilePic,
    this.publisherDesc,
    this.downvotesCount,
    this.upvotesCount,
  });

  String keyId;
  PostContent postContent;
  String publisherId;
  String publisherName;
  String publisherProfilePic;
  String publisherDesc;
  int downvotesCount;
  int upvotesCount;

  factory LiveChannel.fromJson(Map<String, dynamic> json) => LiveChannel(
        keyId: json["key_id"],
        postContent: PostContent.fromJson(json["post_content"]),
        publisherId: json["publisher_id"],
        publisherName: json["publisher_name"],
        publisherProfilePic: json["publisher_profile_pic"],
        publisherDesc: json["publisher_desc"],
        downvotesCount: json["downvotes_count"],
        upvotesCount: json["upvotes_count"],
      );

  Map<String, dynamic> toJson() => {
        "key_id": keyId,
        "post_content": postContent.toJson(),
        "publisher_id": publisherId,
        "publisher_name": publisherName,
        "publisher_profile_pic": publisherProfilePic,
        "publisher_desc": publisherDesc,
        "downvotes_count": downvotesCount,
        "upvotes_count": upvotesCount,
      };
}

class PostContent {
  PostContent({
    this.shortcode,
    this.platformVideoLink,
    this.caption,
    this.description,
  });

  String shortcode;
  String platformVideoLink;
  String caption;
  String description;

  factory PostContent.fromJson(Map<String, dynamic> json) => PostContent(
        shortcode: json["shortcode"],
        platformVideoLink: json["platform_videoLink"],
        caption: json["caption"],
        description: json["description"],
      );

  Map<String, dynamic> toJson() => {
        "shortcode": shortcode,
        "platform_videoLink": platformVideoLink,
        "caption": caption,
        "description": description,
      };
}

class Music {
  Music({
    this.id,
    this.country,
    this.categoryId,
    this.categoryName,
    this.categoryIcons,
    this.playlists,
  });

  dynamic id;
  String country;
  String categoryId;
  String categoryName;
  List<CategoryIcon> categoryIcons;
  List<Playlist> playlists;

  factory Music.fromJson(Map<String, dynamic> json) => Music(
        id: json["_id"],
        country: json["country"],
        categoryId: json["category_id"],
        categoryName: json["category_name"],
        categoryIcons: List<CategoryIcon>.from(
            json["category_icons"].map((x) => CategoryIcon.fromJson(x))),
        playlists: List<Playlist>.from(
            json["playlists"].map((x) => Playlist.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "_id": id,
        "country": country,
        "category_id": categoryId,
        "category_name": categoryName,
        "category_icons":
            List<dynamic>.from(categoryIcons.map((x) => x.toJson())),
        "playlists": List<dynamic>.from(playlists.map((x) => x.toJson())),
      };
}

class CategoryIcon {
  CategoryIcon({
    this.height,
    this.url,
    this.width,
  });

  int height;
  String url;
  int width;

  factory CategoryIcon.fromJson(Map<String, dynamic> json) => CategoryIcon(
        height: json["height"] == null ? null : json["height"],
        url: json["url"],
        width: json["width"] == null ? null : json["width"],
      );

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

class Playlist {
  Playlist({
    this.playlistName,
    this.playlistDescription,
    this.playlistUrl,
    this.playlistTotalTracks,
    this.playlistImages,
    this.playlistFollowers,
    this.playlistId,
  });

  String playlistName;
  String playlistDescription;
  String playlistUrl;
  int playlistTotalTracks;
  List<CategoryIcon> playlistImages;
  int playlistFollowers;
  String playlistId;

  factory Playlist.fromJson(Map<String, dynamic> json) => Playlist(
        playlistName: json["playlist_name"],
        playlistDescription: json["playlist_description"],
        playlistUrl: json["playlist_url"],
        playlistTotalTracks: json["playlist_total_tracks"],
        playlistImages: List<CategoryIcon>.from(
            json["playlist_images"].map((x) => CategoryIcon.fromJson(x))),
        playlistFollowers: json["playlist_followers"],
        playlistId: json["playlist_id"],
      );

  Map<String, dynamic> toJson() => {
        "playlist_name": playlistName,
        "playlist_description": playlistDescription,
        "playlist_url": playlistUrl,
        "playlist_total_tracks": playlistTotalTracks,
        "playlist_images":
            List<dynamic>.from(playlistImages.map((x) => x.toJson())),
        "playlist_followers": playlistFollowers,
        "playlist_id": playlistId,
      };
}

class Publisher {
  Publisher({
    this.platform,
    this.username,
    this.fullName,
    this.profilePicUrl,
    this.content,
    this.keyId,
  });

  Platform platform;
  String username;
  String fullName;
  String profilePicUrl;
  Content content;
  String keyId;

  factory Publisher.fromJson(Map<String, dynamic> json) => Publisher(
        platform: platformValues.map[json["platform"]],
        username: json["username"],
        fullName: json["full_name"],
        profilePicUrl: json["profile_pic_url"],
        content: Content.fromJson(json["content"]),
        keyId: json["key_id"],
      );

  Map<String, dynamic> toJson() => {
        "platform": platformValues.reverse[platform],
        "username": username,
        "full_name": fullName,
        "profile_pic_url": profilePicUrl,
        "content": content.toJson(),
        "key_id": keyId,
      };
}

class Content {
  Content({
    this.description,
  });

  String description;

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

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

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;
  }
}

我试图解析playlist_url的类叫做services。我能够解析播放列表名称和视频数量(计数)

class Services {
  static const String url =
      "https://livetvapi.apyhi.com/api/v2/home?pageLocation=home&countries=IN&app_version=13&"
      "user_id=44edc2c905ae163f&package_id=livetv.movies.freemovies.watchtv.tvshows&os_platform=android";

  static Future<List<String>> loadDataForPlaylistDetailsForButtomTitle() async {
    var res = await http
        .get(url, headers: {'Authorization': dartJsonWebTokenGenerator()});

    if (res.statusCode == 200) {
      print("response is there");
      final homePage = homePageFromJson(res.body);
      Playlist playListObject = new Playlist();
      List<String> lst_names = [];
      for (playListObject in homePage.musicPlaylists.playlists)
        lst_names.add(playListObject.playlistName);

      print("Buttom titles");
      print(lst_names);
      return lst_names;
    } else {
      print("no response");
      return null;
    }
  }

  static Future<List<String>> loadDataForPlaylistDetailsForCount() async {
    var res = await http
        .get(url, headers: {'Authorization': dartJsonWebTokenGenerator()});

    if (res.statusCode == 200) {
      print("response is there");
      final homePage = homePageFromJson(res.body);
      Playlist playListObject = new Playlist();
      List<String> lst_names = [];
      for (playListObject in homePage.musicPlaylists.playlists)
        lst_names.add(playListObject.playlistTotalTracks.toString());
      print("count");
      print(lst_names);
      return lst_names;
    } else {
      print("no response");
      return null;
    }
  }

  static Future<List<Playlist>> loadDataForPlaylistDetailsForImageUrl() async {
    var res = await http
        .get(url, headers: {'Authorization': dartJsonWebTokenGenerator()});

    if (res.statusCode == 200) {
      print("response is there");
      final homePage = homePageFromJson(res.body);
      Music musicObject = new Music();

      List<Playlist> playlistObj = homePage.musicPlaylists.playlists;

      print("category icon object returned");

      return playlistObj;
    } else {
      print("no response");
      return null;
    }
  }
}

这是我要在listView中显示的主文件。首先将数据加载到initstate中,然后存储在数组中。但是对于最后一个(URL内容),我尝试了对象本身的自定义复杂

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
 Services.loadDataForPlaylistDetailsForButtomTitle().then((playListNames) {
      setState(() {
        _playListNames = playListNames ;
      });
    });

    Services.loadDataForPlaylistDetailsForButtomTitle().then((playListCount) {
      setState(() {
        _playListtotalTracks = playListCount ;
      });
    });

    Services.loadDataForPlaylistDetailsForImageUrl().then((objUrl) {
      setState(() {
        _obj = objUrl ;
      });
    });
  }

listView Builder的代码:

Container(
              height: MediaQuery.of(context).size.height * 0.41,
              color: Colors.black,
              child: ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                itemCount: _playListImageUrls.length,
                itemBuilder: (BuildContext context, int index) => Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
                      height: MediaQuery.of(context).size.height * 0.34,
                      child: PhysicalModel(
                        clipBehavior: Clip.antiAliasWithSaveLayer,
                        color: Colors.black,
                        shape: BoxShape.rectangle,
                        borderRadius: BorderRadius.only(
                            topRight: Radius.circular(35),
                            bottomRight: Radius.circular(35)),
                        child: FadeInImage.assetNetwork(
                          width: MediaQuery.of(context).size.width * 0.285,
                          image:  _obj[index].playlistImages[index].url,
                          placeholder: cupertinoActivityIndicator,
                          fit: BoxFit.fill,
                        ),
                      ),
                    ),
                    Container(
                        margin: EdgeInsets.fromLTRB(15, 15, 0, 0),
                        height: MediaQuery.of(context).size.height * 0.03,
                        child: Text(
                            _playListNames[index],
                          style: TextStyle(color: Colors.white),
                        )),
                    Container(
                        margin: EdgeInsets.fromLTRB(15, 0, 0, 0),
                        height: MediaQuery.of(context).size.height * 0.02,
                        child: Text(
                          _playListtotalTracks[index],
                          style: TextStyle(color: Colors.white),
                        ))
                  ],
                ),
              ),
            ),

我也发现自己重复了很多次这种结构,任何即兴创作的建议也将受到欢迎。

1 个答案:

答案 0 :(得分:1)

我终于找到了解决方案。我犯错的全部要点是将事物假定为对象列表,而不是单个对象列表的列表。

进行了以下修改:

在服务文件中

 static Future<List<String>> loadDataForPlaylistDetailsForImageUrl() async {
    var res = await http
        .get(url, headers: {'Authorization': dartJsonWebTokenGenerator()});

    if (res.statusCode == 200) {
      print("response is thereeeeeeeee");
      final homePage = homePageFromJson(res.body);
      Playlist playListObject = new Playlist();
      List<String> urlList = [];
      List<dynamic> lst_names = [];
      for (playListObject in homePage.musicPlaylists.playlists) {
        lst_names.add(playListObject.playlistImages);
        print(lst_names);
      }

      //lst_names=
      print("objjjjjjjjjjjjjjjjjjjj");
      for (var listobj in lst_names) {
        for (var obj in listobj) {
          print(obj.url.toString());
          urlList.add(obj.url.toString());
        }
      }

      return urlList;
    } else {
      print("no response");
      return null;
    }
  }

也在主文件中:

FadeInImage.assetNetwork(
                          width: MediaQuery.of(context).size.width * 0.285,
                          image: _musicPlaylistImgUrlList[index],
                          //_categoryIconfor[index].url,
                          //_obj[index].playlistImages[index].url,
                          placeholder: cupertinoActivityIndicator,
                          fit: BoxFit.none,
                        ),