skip to Main Content

I am working on a nested listview in flutter, I did it like below.

class _SearchResultState extends State<SearchResult> {
  late String searchValue;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    searchValue = widget.searchValue;
    searchData = widget.searchValue;
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              SearchBox(),
              WordDetails(),
              const SizedBox(height: 5),
              DictionaryUsersList(),
              WordMeaning(),
            ],
          ),
        ),
      )
    );
  }
}

class WordMeaning extends StatelessWidget {
  WordMeaning({super.key});

  final json = <Map<String, dynamic>>[
    {
      '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',
        },
      ],
    },
  ];

  @override
  Widget build(BuildContext context) {
    List<Word> words = json.map((json) => Word.fromJson(json)).toList();

    return NestedListView(data: words);
  }
}

class NestedListView extends StatelessWidget {
  final List<Word> data;

  const NestedListView({
    Key? key,
    required this.data,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Expanded(
          child: SizedBox(
            child: ListView.builder(
              physics: const NeverScrollableScrollPhysics(),
              shrinkWrap: true,
              itemCount: data.length,
              itemBuilder: (context, index) {
                List<Meaning> innerList = data[index].meaning;
                return Expanded(
                  child: SizedBox(
                    height: 80,
                    child: Column(
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(4.0),
                          child: Text(data[index].type.toString().toUpperCase()),
                        ),
                        Expanded(
                          child: ListView.builder(
                            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),
                                      ],
                                    )),
                              );
                            },
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          ),
      ),
    );
  }
}

I have 2 issues with this UI.

  1. The inner listview is not fully visible. Please check the below screenshot.

enter image description here

  1. Getting below error when running the application:

======== Exception caught by widgets library =======================================================
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.

The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type ParentData.

Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a RepaintBoundary widget.

I tried wrapping the Expanded widget with a Column like below:

Widget build(BuildContext context) {
  return SingleChildScrollView(
    child: Column(
      children: [
        Expanded(
          child: SizedBox(
            child: ListView.builder(
              physics: const NeverScrollableScrollPhysics(),
              shrinkWrap: true,
              itemCount: data.length,
              itemBuilder: (context, index) {
                List<Meaning> innerList = data[index].meaning;
                return SizedBox(
                  height: 80,
                  child: Column(
                    children: [
                      Padding(
                        padding: const EdgeInsets.all(4.0),
                        child: Text(data[index].type.toString().toUpperCase()),
                      ),
                      Expanded(
                        child: SizedBox(
                          height: 80,
                          child: 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),
                                    ],
                                  ),
                                ),
                              );
                            },
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
        ),
      ],
    ),
  );
}

But at that time getting another error like below:

======== Exception caught by rendering library =====================================================
The following assertion was thrown during paint():
RenderBox was not laid out: RenderRepaintBoundary#50ab9 relayoutBoundary=up2 NEEDS-PAINT
‘package:flutter/src/rendering/box.dart’:
Failed assertion: line 1966 pos 12: ‘hasSize’

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.

2

Answers


  1. You’ve used Expanded widget in ListView and in SingleScrollChildView, it is only applicable in Row and Column. Simply remove Expanded from these and it will be fixed.

    Login or Signup to reply.
  2. The more you go nested, the more complex is to handle the UI. Try to modify like below. You need to do fourchanges.

    1. Remove SingleChildScrollView, Expanded, SizedBox and keep it as a simple hierarchy.

    2. Add physics for Inner Listview.

    3. Set mainaxis size for Column

    4. Wrap Wordmeaning() class with Expanded

      class NestedListView {
       build(){    
           return ListView.builder(
                     physics: const NeverScrollableScrollPhysics(),
                     shrinkWrap: true,
                     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()),
                               ),
                               Expanded(
                                 child : ListView.builder(
                                   shrinkWrap: true,
                                   physics: const NeverScrollableScrollPhysics(), //#2 Add this line
                                   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(
                                           mainAxisSize : MainAxisSize.max, // #3 Add this line
                                             children: [
                                               Text(product.description),
                                               Text(product.example),
                                             ]
                                           ))
                                     );
                                   })
                                ])               
                           })
                      }    
      }
      

      // No change here

      class WordMeaning extends StatelessWidget {
      
           build(){
                   List<Word> words = json.map((json) => Word.fromJson(json)).toList();    
                   return NestedListView(data: words);
           }    
      

      }

      class _SearchResultState extends State<SearchResult> {
      
           build(){
               return Scaffold(
               backgroundColor: Colors.white,
               body: SafeArea(
               child: SingleChildScrollView(
                 child: Column(
                   children: [
                     SearchBox(),
                     WordDetails(),
                     const SizedBox(height: 5),
                     DictionaryUsersList(),
                     Expanded(
                       child : WordMeaning()    // #4 Wrap this with Expanded or Flexible
                       ),
                   ],
                 ),
               ),
             )
           );
       }
      

      }

    This should build your UI as expected. Let me know if that works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search