如何在 Flutter ListView 的构建过程中测试 json 属性是不是存在

Posted

技术标签:

【中文标题】如何在 Flutter ListView 的构建过程中测试 json 属性是不是存在【英文标题】:How to test if json property is present during the build of a Flutter ListView如何在 Flutter ListView 的构建过程中测试 json 属性是否存在 【发布时间】:2019-10-03 18:49:17 【问题描述】:

我是 Flutter 和 Dart 的初学者。

我有一个本地 JSON 文件,阅读它,我想在 ListView 中显示 JSON 数据。 但在我的 JSON 数据中,我并不总是拥有所有不同的属性。 所以当我想显示一个文本时,属性的值是不存在的,因为该属性不存在(在这种情况下是属性“描述”。

我该如何解决?

提前感谢您的帮助

我试过三元运算符 我尝试使用函数 containsKey

但也许我做到了?

... json

[
  
    "createdBy": "bddae0de-320c-41a9-a69b-75793758b7a7",
    "description": "Fhjifgsdsdsd",
    "endDateTime": "1477490400000",
    "hasPicture": "false",
    "isActive": "true",
    "isAdminActive": "true",
    "maxParticipants": "50",
    "startDateTime": "1476799200000",
    "title": "Song Church Story Telling",
    "type": "Music"
  ,
  
    "createdBy": "-KHzgxS6KBqu1rNmJzpT",
    "endDateTime": "1476378000000",
    "hasPicture": "false",
    "isActive": "true",
    "isAdminActive": "true",
    "startDateTime":"1476205200000",
    "title": "Test greg T",
    "titleDate": "Tuesday, 11 Oct 8:00 PM",
    "type": "Games"
  
]

...

...颤抖

  Widget build(BuildContext context) 
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Load local JSON file"),
        ),
        body: new Container(
          child: new Center(
            // Use future builder and DefaultAssetBundle to load the local JSON file
            child: new FutureBuilder(
                future: DefaultAssetBundle.of(context)
                    .loadString('assets/data/ckevents_data.json'),
                builder: (context, snapshot) 
                  // Decode the JSON
                  var newData = json.decode(snapshot.data.toString());

                  return new ListView.builder(
                    // Build the ListView
                    itemBuilder: (BuildContext context, int index) 
                      return new Card(
                        child: new Column(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                            new Text("Title: " + newData[index]['title'],
                                style: new TextStyle(
                                    fontSize: 20.0, color: Colors.blue)),
                            new Text(
                                "Description: " +
                                        ((newData[index].containsKey('description')) ? ('') : (newData[index]['description'])),
                                style: new TextStyle(
                                    fontSize: 10.0, color: Colors.pink)),
                            new Text("Categorie: " + newData[index]['type'],
                                style: new TextStyle(
                                    fontSize: 15.0, color: Colors.red)),
                            new Text(
                                "Date: " +
                                    DateTime.fromMillisecondsSinceEpoch(
                                            newData[index]['startDateTime'])
                                        .add(Duration(days: 700))
                                        .toString(),
                                style: new TextStyle(
                                    fontSize: 10.0, color: Colors.black))
                          ],
                        ),
                      );
                    ,
                    itemCount: newData == null ? 0 : newData.length,
                  );
                ),
          ),
        ));
  

...

【问题讨论】:

【参考方案1】:

您可以像这样使用空合并运算符:

 new Text("Description: " + newData[index]['description'] ?? ''),

如果存在则打印描述,如果不存在则打印空字符串。

【讨论】:

您好,感谢您的快速回复。我已经尝试过这个解决方案。也许我做错了什么。使用您的解决方案,我仍然有一个错误,仅显示第一个项目,并且在我在电话上收到消息后:无效的 Argumet(s) 在 VSCode 中,我的错误与以前相同。谢谢朱利安,其他想法是我的问题吗? 看我上面的回复 据我所知,在您的代码中,您使用三元 ? 运算符。在这个答案中,我告诉你使用空合并运算符?? 它是不同的。你也试过了吗?【参考方案2】:

试试这个方法 1.像这样为您的响应json制作模型类..

class UserData 
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;

UserData(this.albumId, this.id, this.title, this.url, this.thumbnailUrl);

factory UserData.fromJson(Map<String, dynamic> json) 
return new UserData(
    albumId: json['albumId'],
    id: json['id'],
    title: json['title'],
    url: json['url'],
    thumbnailUrl: json['thumbnailUrl']);


现在制作列表对象..

  List<UserData> list = List();

然后添加数据..

list = (json.decode(response.body) as List)
      .map((data) => UserData.fromJson(data))
      .toList();

这样读取json文件..

class _ApiCallScreenState extends State<ApiCallScreen> 
@override
void initState() 
String data = await  DefaultAssetBundle.of(context).loadString("assets/data.json");
 list = (json.decode(data) as List)
  .map((data) => UserData.fromJson(data))
  .toList();
super.initState();

【讨论】:

嗨,谢谢您的回复,我已经尝试过这样的解决方案,我的课程已经存在,应该是下一步使用它,但是当我尝试使用它时,我首先从资产中的 json 文件创建我的列表的问题。不知道为什么,也许读取文件和创建列表的功能不正确?这就是为什么我首先尝试了一种简化的方法,但我遇到了缺少属性的问题,无法对其进行测试,如果不存在则跳过它。 谢谢你把它放在哪里,但是我必须使用哪个函数来读取文件。在您的解决方案中,数据可能是一个文件?还是我必须使用类似的函数: String data = await DefaultAssetBundle.of(context).loadString("assets/data/ckevents_data.json");然后像你为列表做的那样做吗?

以上是关于如何在 Flutter ListView 的构建过程中测试 json 属性是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter ListView 的构建过程中测试 json 属性是不是存在

Flutter - 如何更新用于构建 ListView 的 Future/List 的状态(或值?)(通过 FutureBuilder)

如何使用提供程序在 Flutter ui 中使用 api 响应获取 ListView 构建器数据

Flutter ListView 在构建时滚动到底部

如何在 Flutter 中添加 ListView.builder 的填充顶部?

Flutter - 如何使列屏幕可滚动