skip to Main Content

I am trying to create a UI like below:

enter image description here

My UI has an inner list and an outer list and the data count is dynamic.

Sample Json:

{
    'type': 'adjective',
    'meaning': [
      {
        'description': 'description 1',
        'example': 'example 1'
      },
      {
        'description': 'description 2',
        'example': 'example 2'
      },
      {
        'description': 'description 3',
        'example': 'example 3'
      },
      {
        'description': 'description 4',
        'example': 'example 4'
      },
    ]
},
{
    'type': 'noun',
    'meaning': [
      {
        'description': 'description 1',
        'example': 'example 1'
      },
      {
        'description': 'description 2',
        'example': 'example 2'
      },
    ]
},
{
    'type': 'verb',
    'meaning': [
      {
        'description': 'description 1',
        'example': 'example 1'
      },
    ]
},
{
    'type': 'adverb',
    'meaning': [
      {
        'description': 'description 1',
        'example': 'example 1'
      },
      {
        'description': 'description 2',
        'example': 'example 2'
      },
      {
        'description': 'description 3',
        'example': 'example 3'
      },
    ]
},

How can I create a UI like this? Using what kind of widgets I can do this? Is it possible to add the sample json on the code?

2

Answers


  1. Question 1 : You can create the UI like the image you shared by nested list view.

    Here is the code : (you can modify it as per your requirements)

    NestedListView.dart

    import 'package:flutter/material.dart';
    import '.../model/Word.dart';
    
    class NestedListView extends StatelessWidget {
      final List<Word> data;
    
      const NestedListView({
        Key? key,
        required this.data,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ListView.builder(
            itemCount: data.length,
            itemBuilder: (context, index) {
              List<Meaning> innerList = data[index].meaning;
    
              return Column(
                children: [
                  Padding(
                    padding: const EdgeInsets.all(4.0),
                    child: Text(data[index].type.toString().toUpperCase()),
                  ),
                  ListView.builder(
                    physics: const NeverScrollableScrollPhysics(),
                    shrinkWrap: true,
                    itemCount: innerList.length,
                    itemBuilder: (context, index) {
                      final product = innerList[index];
                      return Padding(
                        padding: const EdgeInsets.all(4.0),
                        child: Container(
                            color: Colors.grey,
                            child: Column(
    
                              children: [
                                Text(product.description),
                                Text(product.example),
                              ],
                            )),
                      );
                    },
                  ),
                ],
              );
            },
          ),
        );
      }
    }
    

    Question 2 :
    Here is the model file which will take care of the nested list data.
    Word.dart

    class Word {
      final String type;
      final List<Meaning> meaning;
    
      Word({
        required this.type,
        required this.meaning,
      });
    
      factory Word.fromJson(Map<String, dynamic> json) {
        return Word(
          type: json['type'],
          meaning: List<Meaning>.from(
            json['meaning'].map((meaning) => Meaning.fromJson(meaning)),
          ),
        );
      }
    
      Map<String, dynamic> toJson() => {
        'type': type,
        'meaning': meaning.map((meaning) => meaning.toJson()).toList(),
      };
    }
    
    class Meaning {
      final String description;
      final String example;
    
      Meaning({
        required this.description,
        required this.example,
      });
    
      factory Meaning.fromJson(Map<String, dynamic> json) {
        return Meaning(
          description: json['description'],
          example: json['example'],
        );
      }
    
      Map<String, dynamic> toJson() => {
        'description': description,
        'example': example,
      };
    }
    

    Let me know whether it solves your problem.

    Login or Signup to reply.
  2. Hi To show a list inside another list from JSON data in Flutter, you can use nested ListView.builder.

    List<Map<String, dynamic>> data = [
      {
        'type': 'adjective',
        'meaning': [
          {'description': 'description 1', 'example': 'example 1'},
          {'description': 'description 2', 'example': 'example 2'},
          {'description': 'description 3', 'example': 'example 3'},
          {'description': 'description 4', 'example': 'example 4'},
        ]
      },
      {
        'type': 'noun',
        'meaning': [
          {'description': 'description 1', 'example': 'example 1'},
          {'description': 'description 2', 'example': 'example 2'},
        ]
      },
      {
        'type': 'verb',
        'meaning': [
          {'description': 'description 1', 'example': 'example 1'},
        ]
      },
      {
        'type': 'adverb',
        'meaning': [
          {'description': 'description 1', 'example': 'example 1'},
          {'description': 'description 2', 'example': 'example 2'},
          {'description': 'description 3', 'example': 'example 3'},
        ]
      },
    ];
    
    ListView.builder(
      itemCount: data.length,
      itemBuilder: (context, index) {
        final item = data[index];
        final type = item['type'];
        final meanings = List<Map<String, String>>.from(item['meaning']);
    
        return Card(
          margin: EdgeInsets.all(8),
          child: Column(
            children: [
              ListTile(
                title: Text(type),
              ),
              ListView.builder(
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                itemCount: meanings.length,
                itemBuilder: (context, subIndex) {
                  final meaning = meanings[subIndex];
                  final description = meaning['description'];
                  final example = meaning['example'];
    
                  return ListTile(
                    title: Text(description),
                    subtitle: Text(example),
                  );
                },
              ),
            ],
          ),
        );
      },
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search