Flutter:JSON 数据,列表下列表

Flutter: JSON data , list under list

我有 JSON 数据文件,如下所示,您可以看到电子邮件本身就是一个列表:

[
    {
        "index": 0,
        "about": "text text text",
        "email": [
            "kjdkffsk@skfjsd.com",
            "kjdkffsk@skfjsd.com",
        ],
        "name": "sample name",
        "picture": "https://kdjfksfjsdklfs.com"
    },
    {
        "index": 1,
        "about": "text text text",
        "email": [
            "kjdkffsk@skfjsd.com",
            "kjdkffsk@skfjsd.com",
        ],
        "name": "sample name ",
        "picture": "https://kdjfksfjsdklfs.com"
    },
    {
        "index": 2,
        "about": "text text text",
        "email": [
            "kjdkffsk@skfjsd.com",
            "kjdkffsk@skfjsd.com",
        ],
        "name": "sample name",
        "picture": "https://kdjfksfjsdklfs.com"
    }
]

我的代码如下,它基本上是一个从上面获取数据的列表视图构建器JSON。现在,当单击列表时,它会导航到下一页,我需要在其中显示该用户的详细信息。

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

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

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

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

  final String title;

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

Future _data;

class _MyHomePageState extends State<MyHomePage> {
  Future<List<User>> _getUsers() async {
    var data =
        await DefaultAssetBundle.of(context).loadString("assets/test.json");

    var jsonData = json.decode(data);

    List<User> users = [];

    for (var u in jsonData) {
      User user =
          User(u["index"], u["about"], u["name"], u["email"], u["picture"]);

      users.add(user);
    }

    print(users.length);

    return users;
  }

  @override
  void initState() {
    super.initState();
    _data = _getUsers();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: Container(
        child: FutureBuilder(
          future: _data,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            print(snapshot.data);
            if (snapshot.data == null) {
              return Container(child: Center(child: Text("Loading...")));
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    leading: CircleAvatar(
                      backgroundImage:
                          NetworkImage(snapshot.data[index].picture),
                    ),
                    title: Text(snapshot.data[index].name),
                    // subtitle: Text(snapshot.data[index].email),
                    onTap: () {
                      Navigator.push(
                          context,
                          new MaterialPageRoute(
                              builder: (context) =>
                                  DetailPage(snapshot.data[index])));
                    },
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {
  final User user;

  DetailPage(this.user);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(user.name),
      ),
      body: Container(
        child: Text(user.about),
      ),
    );
  }
}

class User {
  final int index;
  final String about;
  final String name;
  final String email;
  final String picture;

  User(this.index, this.about, this.name, this.email, this.picture);
}

我想在第二页中为名称和电子邮件创建 Listview Builder,以便在名称下列出所有电子邮件。

有人可以帮助我无法生成第二页列表,尤其是电子邮件列表。

首先: 您可以使用

  • 摩尔/moor_flutter moor flutter_moor
  • built_value built_value

    映射 json 字符串并生成 fromJson/toJson 函数。

    使用沼泽的例子:
  • 首先,创建一个沼泽数据库(如果您有任何问题,我很乐意回答)。
  • 其次,这将是您应该使用的 class。
import 'dart:convert';
import 'package:db/moordb/database.dart';
import 'package:json_annotation/json_annotation.dart' as json;
import 'package:moor/moor.dart';

part 'user.g.dart';

@DataClassName("User")
class Users extends Table {
  IntColumn get id => integer().nullable().autoIncrement()();

  @JsonKey("index")
  IntColumn get index => text().nullable()();

  @JsonKey("about")
  TextColumn get about => text().nullable()();

  @JsonKey("email")
  TextColumn get emails => text().map(const EmailConverter()).nullable()();

  @JsonKey("name")
  TextColumn get name => text().nullable()();

  @JsonKey("picture")
  TextColumn get picture => text().nullable()();

  @override
  Set<Column> get primaryKey => {id};
}

class EmailConverter extends TypeConverter<List<String>, String> {
  const EmailConverter ();

  @override
  List<String> mapToDart(String fromDb) {
    if (fromDb == null) {
      return null;
    }
    List _emails = List<String>();
    (jsonDecode(fromDb)).forEach((value) {
      _emails.add(value);
    });
    return _emails;
  }

  @override
  String mapToSql(List<dynamic> value) {
    if (value == null) {
      return null;
    }
    return jsonEncode(value);
  }
}

第二个:

您最好通过以下方式发送用户对象:

在您的情况下,您是将对象直接传递给小部件。
总之,很明显,您的 User 对象中的 String 字段 email 没有被包含列表中电子邮件的解码数据填充。 (因为您使用的是 Class 用户)。

注意:丢失 new 关键字,因为 Dart 2 不再需要它

看看这个例子,告诉我它是否适合你:

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

import 'package:json_parsing_example/models.dart';

// To parse this JSON data, do
//
//     final user = userFromJson(jsonString);

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

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

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

  final String title;

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

Future _data;

class _MyHomePageState extends State<MyHomePage> {
  Future<List<User>> _getUsers() async {
    var data =
        await DefaultAssetBundle.of(context).loadString("json/parse.json");

    return userFromJson(data);
  }

  @override
  void initState() {
    super.initState();
    _data = _getUsers();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: Container(
        child: FutureBuilder<List<User>>(
          future: _data,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            print(snapshot.data);
            if (snapshot.data == null) {
              return Container(child: Center(child: Text("Loading...")));
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    leading: CircleAvatar(
                      backgroundImage:
                          NetworkImage(snapshot.data[index].picture),
                    ),
                    title: Text(snapshot.data[index].name),
                    // subtitle: Text(snapshot.data[index].email),
                    onTap: () {
                      Navigator.push(
                          context,
                          new MaterialPageRoute(
                              builder: (context) =>
                                  DetailPage(snapshot.data[index])));
                    },
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

class DetailPage extends StatefulWidget {
  final User user;

  DetailPage(this.user);

  @override
  _DetailPageState createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.user.name),
      ),
      body: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                widget.user.name,
                style: TextStyle(fontSize: 20),
              ),
            ),
            ListView.builder(
              shrinkWrap: true,
              itemCount: widget.user.email.length,
              itemBuilder: (BuildContext context, int index) {
                return Card(
                    child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text(widget.user.email[index]),
                ));
              },
            ),
          ],
        ),
      ),
    );
  }
}


您的模型class:

// To parse this JSON data, do
//
//     final user = userFromJson(jsonString);

import 'dart:convert';

List<User> userFromJson(String str) => List<User>.from(json.decode(str).map((x) => User.fromJson(x)));

String userToJson(List<User> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class User {
    User({
        this.index,
        this.about,
        this.email,
        this.name,
        this.picture,
    });

    int index;
    String about;
    List<String> email;
    String name;
    String picture;

    factory User.fromJson(Map<String, dynamic> json) => User(
        index: json["index"],
        about: json["about"],
        email: List<String>.from(json["email"].map((x) => x)),
        name: json["name"],
        picture: json["picture"],
    );

    Map<String, dynamic> toJson() => {
        "index": index,
        "about": about,
        "email": List<dynamic>.from(email.map((x) => x)),
        "name": name,
        "picture": picture,
    };
}