【问题标题】:Display nested json array in ListView在 ListView 中显示嵌套的 json 数组
【发布时间】:2021-10-08 08:11:53
【问题描述】:

我有以下 json

{
  "time": [
    [
      {
        "date": "1",
        "available": "2"
      },
      {
        "date": "2",
        "available": "2"
      },
      {
        "date": "3",
        "available": "3"
      }
    ],
    [
      {
        "date": "1",
        "available": "2"
      },
      {
        "date": "2",
        "available": "2"
      },
      {
        "date": "3",
        "available": "2"
      }
    ]
  ]
}



这个 json 有一个包含 2 个对象列表的时间数组。这个数字是可变的,我想将它们显示为另一个列表视图中的列表视图

【问题讨论】:

  • 您好 - 如果您可以包含您尝试过的代码,这可能会有所帮助,您希望获得帮助。

标签: json flutter rest


【解决方案1】:

这个过程有两个步骤。最好先将此 json 映射到数据结构。然后您可以显示对象。您可以在答案底部的浏览器中试用一个工作示例

映射到数据结构

假设您将有以下课程:

class TimeSlot {
  final String date;
  final String available;

  TimeSlot(this.date, this.available);
}

您可以手动实现fromJson 方法,或使用json_serializable 包并简单地注释类。在本例中,我将手动完成。

TimeSlot.fromJson(Map<String, dynamic> json)
    : date = json['date'],
        available = json['available'];

现在您已完成此设置,您可以将 json 字符串映射到此结构。嵌套数组的结构使这变得相当复杂。

import 'dart:convert';

final json = jsonDecode(myJson);
final timeJson = (json['time'] as List<dynamic>).cast<List<dynamic>>();
final List<List<TimeSlot>> time = timeJson.map((timeGroup) {
  return timeGroup.map((item) {
    return TimeSlot.fromJson(item as Map<String, dynamic>);
  }).toList();
}).toList();

显示数据

嵌套ListView 小部件可能会因为嵌套它们的滚动行为而导致问题。这是一个示例,您可以如何同时使用 ListViewColumn

return ListView.separated(
  itemCount: time.length,
  separatorBuilder: (_, index) => Divider(),
  itemBuilder: (_, outerIndex) {
    final group = time[outerIndex];
    return Column(
      children: 
        group.map((slot) => ListTile(
          title: Text("date: ${slot.date}"),
          subtitle: Text("available: ${slot.available}"),
        )).toList(),
    );
  }
);

工作示例

我在 DartPad 上做了一个工作示例:https://dartpad.dev/?id=b8d6d72a1359c6b9f638480d667f5cf9&null_safety=true

其他资源

查看 Flutter 开发网站上的 JSON and serialization 部分。

【讨论】:

  • 当然。祝你好运:) 如果有帮助,请随时投票 ;-)
【解决方案2】:

使用这个:

var data = json.decode(YOUR_RESPONSE);
List<List<Map, dynamic>> timeList= json.decode(data["time"]);

然后您可以在ListView.builder 中使用它们:

ListView.builder{
   itemCount:timeList.length,
   itemBuilder: (ctx, index){
      List<Map, dynamic> temp = timeList[index];
      return ListView.builder{
         itemCount:temp.length,
         itemBuilder: (ctx1, index1){
               // now you have access to each element by temp[index1] an you 
                // can return it
      }
    }
}

【讨论】:

  • 工作得很好,,但我无法滚动项目,即使我把它放在滚动视图中
  • 分享你的代码,我可以帮你搞定
  • 您是否尝试将您的Appoinmentd 放在一个固定高度的大小容器中,所以您可以检查此问题是否与您的Appoinmentd 小部件或主要小部件有关!让我知道结果。如果它不再滚动,我们应该检查子小部件。
  • 可以来任何桌子吗?
【解决方案3】:

我认为嵌套的 ListView 并没有提供最好的性能。 如果我们使用列作为内部列表,那么这在性能方面也不好,Bcz 如果内部列表有 1000 个项目,那么所有视图都是在某个时间创建的。

您可以将 NestedList 数据转换为 FlatterdList,然后使用一个 ListView。

模型类

class TimeSlot {
  final String date;
  final String available;

  TimeSlot(this.date, this.available);
}

将 json 解析为模型

final json = jsonDecode(myJson);
final timeJson = (json['time'] as List<dynamic>).cast<List<dynamic>>();
final List<List<TimeSlot>> time = timeJson.map((timeGroup) {
  return timeGroup.map((item) {
    return TimeSlot.fromJson(item as Map<String, dynamic>);
  }).toList();
}).toList();

将时间转换为flatteredTime

List<TimeSlot> flatteredTime = time.expand((i) => i).toList();

然后显示

ListView.builder(
         itemCount:flatteredTime.length,
         itemBuilder: (ctx1, index1){
               // now you have access to each element by flatteredTime[index1] an you 
                // can return it
      )

我们也可以使用官方文档中给出的混合列表

https://flutter.dev/docs/cookbook/lists/mixed-list

但不知道哪个是最好的方法。 任何人都有最好的解决方案,请在此处发表评论。

【讨论】:

    猜你喜欢
    • 2019-12-11
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多