john math
john math

Reputation: 55

Display nested json array in ListView

I have the following 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"
      }
    ]
  ]
}



This json has a time array which contains 2 lists of objects. This number is variable I want to makedisplay these as list views inside of another listview

Upvotes: 2

Views: 329

Answers (3)

Makwana Mehul
Makwana Mehul

Reputation: 434

I think nested ListView is not give the best performance. and if we use column for inner list then this also not good in terms of performance, Bcz if inner list has 1000 item then all View are create at some time.

You can convert you NestedList data in to FlatterdList and then use one ListView.

Model class

class TimeSlot {
  final String date;
  final String available;

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

Parse json to model

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();

Convert time into flatteredTime

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

Then display

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

And we can also use mixed-list like given in official doc

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

But dont know which is the best way. any one has best solution then pls comment here.

Upvotes: 0

dumazy
dumazy

Reputation: 14435

There are two steps in this process. Preferably you'll start by mapping this json to a data structure. Then you can display the objects. There's a working example you can try out in your browser at the bottom of the answer

Mapping to a data structure

Let's say you'll have the following class:

class TimeSlot {
  final String date;
  final String available;

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

You can manually implement a fromJson method, or use the json_serializable package and simply annotate the class. I'll do it manually in this example.

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

Now that you have this set up, you can map your json string to this structure. Having a structure of nested arrays makes this quite complex.

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();

Displaying the data

Having nested ListView widgets might cause issues because of nesting their scrolling behavior. Here's an example how you can use both ListView and Column for this.

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(),
    );
  }
);

Working example

I've made a working example here on DartPad: https://dartpad.dev/?id=b8d6d72a1359c6b9f638480d667f5cf9&null_safety=true

Additional resources

Check out the section on JSON and serialization on the Flutter dev site.

Upvotes: 2

Abbasihsn
Abbasihsn

Reputation: 2171

use this:

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

then you can use them inside a 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
      }
    }
}

Upvotes: 0

Related Questions