【问题标题】:Flutter: how to display data from a parsed json object containing a list of objectsFlutter:如何显示来自包含对象列表的已解析 json 对象的数据
【发布时间】:2020-02-04 17:26:35
【问题描述】:

从assets文件夹中解析出本地JSON对象后,无法在屏幕上显示内容,我已经用了两天了,请记住我是编程和flutter开发的新手刚从 udemy 课程毕业,这是我的第一个项目。如果能得到任何帮助,我将不胜感激。

我的 JSON 文件

{
 "movies": [
  {
   "name": "JOKER",
   "actors": [
     {
       "name1": "Joaquin Phoenix"
     },
     {
       "name2": "Robert De Niro"
     },
     {
      "name3": "Zazie Beetz"
     }
  ],
   "category": [
     {
      "genre1": "Crime"
     },
     {
      "genre2": "Drama"
     },
     {
      "genre3": "Thriller"
     }
   ],
   "timeM": "121",
   "text": "A gritty character study of Arthur Fleck, a man disregarded by society.",
   "image": "image url",

 ***there are 4 more similar objects within the movies list***
},

我的 JSON 模型类

import 'dart:convert';

MovieList movieListFromJson(String str) => MovieList.fromJson(json.decode(str));

class MovieList {
    List<Movie> movies;

    MovieList({ this.movies,});

    factory MovieList.fromJson(Map<String, dynamic> json) => MovieList(
        movies: List<Movie>.from(json["movies"].map((x) => Movie.fromJson(x))),
    );
}

class Movie {
    String name;
    List<Actor> actors;
    List<Category> category;
    String timeM;
    String text;
    String image;

    Movie({ this.name, this.actors, this.category, this.timeM, this.text, this.image,});

    factory Movie.fromJson(Map<String, dynamic> json) => Movie(
        name: json["name"],
        actors: List<Actor>.from(json["actors"].map((x) => Actor.fromJson(x))),
        category: List<Category>.from(json["category"].map((x) => Category.fromJson(x))),
        timeM: json["timeM"] == null ? null : json["timeM"],
        text: json["text"],
        image: json["image"],
    );
}

class Actor {
    String name1;
    String name2;
    String name3;

    Actor({this.name1,this.name2,this.name3,
    });

    factory Actor.fromJson(Map<String, dynamic> json) => Actor(
        name1: json["name1"] == null ? null : json["name1"],
        name2: json["name2"] == null ? null : json["name2"],
        name3: json["name3"] == null ? null : json["name3"],
    );
}

class Category {
    String genre1;
    String genre2;
    String genre3;

    Category({this.genre1,this.genre2,this.genre3,
    });

    factory Category.fromJson(Map<String, dynamic> json) => Category(
        genre1: json["genre1"] == null ? null : json["genre1"],
        genre2: json["genre2"] == null ? null : json["genre2"],
        genre3: json["genre3"] == null ? null : json["genre3"],
    );
}

我的小部件类

class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}

class _AppState extends State<App> {
var movies;

void loadAsset() async {
  final response = await rootBundle.loadString('assets/movies.json');
  final movieModel = movieListFromJson(response);

  setState(() {
    movies = movieModel;
  });
}

_AppState() {
  loadAsset();
}

@override
Widget build(BuildContext context) {
  return MaterialApp(
    debugShowCheckedModeBanner: true,
    home: Scaffold(
    body: Text(movies[2].category[1].genre1),
    appBar: AppBar(
      title: Text('movie schedules'),
      ),
    ),
  );
}

}

【问题讨论】:

  • 如果在 setState 之前打印 response/movieModel 会发生什么?顺便说一句,您可以尝试使用 initState() 而不是 AppState 的构造函数

标签: json flutter dart


【解决方案1】:

从新手到新手 我的朋友喜欢你的 gitrepo :) https://github.com/nitinsingh9x/flutterFutureBuilder

class _AppState extends State<App> {
  @override
  Widget build(BuildContext context) {
    `return FutureBuilder(`
      future: rootBundle.loadString('assets/movies.json'),
      builder: (BuildContext context, AsyncSnapshot snap) {
        if (snap.hasData) {
          var movies = movieListFromJson(snap.data);
          return Scaffold(
              appBar: AppBar(
                  backgroundColor: Colors.deepPurple, title: Text('Movies')),
              body: Column(
                children:
                    movies.movies.map((movie) => Text(movie.name)).toList(),
              ));
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }
}

【讨论】:

    【解决方案2】:

    一个非常优雅的解决方案是使用 FutureBuilder 来处理读取文件的异步操作。它会像这样美丽:

    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        debugShowCheckedModeBanner: true,
        home: Scaffold(
        body: FutureBuilder(
          future: 
          builder: (context, snapshot) {
            if (snapshot.hasData()) {
              return Text(snapshot.data[2].category[1].genre1),
            }
            return CircularProgressIndicator();
          }
        )
        appBar: AppBar(
          title: Text('movie schedules'),
          ),
        ),
      );
    }
    

    您甚至会获得一个 CircularProgressIndicator 来指示您正在加载文件

    【讨论】:

    • 非常感谢,还有一件事。解析 json 后,返回一个包含 List 的 MovieList 对象。我想访问电影列表并使用类似 For Loop 的东西来访问特定电影并访问其信息,只要我传递我想要访问的元素的位置。简单地说,我想创建/访问 JSON 模型类之外的电影列表
    【解决方案3】:

    如果这是问题,我不知道,但请尝试使用 initState 而不是构造函数。

    initState() {
       final response = await rootBundle.loadString('assets/movies.json');
       final movieModel = movieListFromJson(response);
    
       setState(() {
          movies = movieModel;
       });
    } 
    

    在正文中,设置是否在未加载 JSON 时显示某些内容。

    ...
    body: movies ? Text(movies[2].category[1].genre1) : CircularProgressIndiciator(),
    ...
    

    【讨论】:

      猜你喜欢
      • 2020-07-29
      • 2021-05-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      相关资源
      最近更新 更多