Search code examples
flutterlistviewflutter-listview

How to nest listview in listview in flutter?


I am trying to nest the ListView in a Listview as per the below code, the Listview on top is scrolling horizontally and the nested ListView is scrolling vertically . for the nested ListView I am facing the error of

Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a vertical viewport was given an unlimited amount of horizontal space in which to expand.

How should I resolve it so that the Nested View is also shown in the below code?

new Container(
        child: new ListView(
          
          scrollDirection: Axis.horizontal,
           children: <Widget>[
            ListView(
              

              scrollDirection:Axis.vertical,
              children: <Widget>[new Container(
                padding: EdgeInsets.fromLTRB(10, 20,10, 0),
                
                width: screenSize.width,
                child: new Column(
                  children: <Widget>[
                    Column(children: <Widget>[
                      Row(children: <Widget>[
                        Text('Text1'),
                        Text('Text1'),
                      ],),
                      Row(children: <Widget>[
                        Text('Text1'),
                        Text('Text1'),
                      ],),

                    ],),
                    
                    new Container(
                     //ERROR POINT
                      child: new ListView(
                        scrollDirection: Axis.vertical,
                        shrinkWrap: true,
                        children: <Widget>[
                          new Container(
                            color: Colors.red,
                            width: screenSize.width,
                             child: new Center(
                              child: new Text(
                                'RED',
                                style: new TextStyle(
                                    fontSize: 40.0,
                                    color: Colors.white
                                ),
                              ),
                            ),
                          ),
                          new Container(
                            color: Colors.blue,
                            width: screenSize.width,
                            child: new Center(
                              child: new Text(
                                'BLUE',
                                style: new TextStyle(
                                    fontSize: 40.0,
                                    color: Colors.white
                                ),
                              ),
                            ),
                          ),
                          new Container(
                            color: Colors.orange,
                            width: screenSize.width,
                            child: new Center(
                              child: new Text(
                                'ORANGE',
                                style: new TextStyle(
                                    fontSize: 40.0,
                                    color: Colors.white
                                ),
                              ),
                            ),
                          )
                        ],
                      ),
                    )
                  ],
                ),
              ),],
            ),
            new Container(
              color: Colors.blue,
              width: screenSize.width,
              child: new Center(
                child: new Text(
                  'BLUE',
                  style: new TextStyle(
                      fontSize: 40.0,
                      color: Colors.white
                  ),
                ),
              ),
            ),
            new Container(
              color: Colors.orange,
              width: screenSize.width,
              child: new Center(
                child: new Text(
                  'ORANGE',
                  style: new TextStyle(
                      fontSize: 40.0,
                      color: Colors.white
                  ),
                ),
              ),
            )
          ],
        ),
      )

Solution

  • DO NOT wrap widgets with an empty Container

    For nested ListView you have to constrain its width via either SizedBox or Container, like so:

    ListView(
      scrollDirection: Axis.horizontal,
      children: [
        SizedBox(
          child: ListView(
            children: [
              Text('data'),
              Text('data'),
              Text('data'),
            ],
          ),
          width: 300,
        ),
        SizedBox(
          child: ListView(
            children: [
              Text('data'),
              Text('data'),
              Text('data'),
            ],
          ),
          width: 300,
        ),
        SizedBox(
          child: ListView(
            children: [
              Text('data'),
              Text('data'),
              Text('data'),
            ],
          ),
          width: 300,
        ),
      ],
    )
    

    If you want to keep all nested scroll views positions you could wrap them in a SingleChildScrollView with Row, but it seems something is not quite right in your decision

    SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: [
            SizedBox(
              width: 200,
              child: ListView.builder(
                itemBuilder: (context, index) => Text('data $index'),
                itemCount: 200,
              ),
            ),
            SizedBox(
              width: 200,
              child: ListView.builder(
                itemBuilder: (context, index) => Text('data $index'),
                itemCount: 200,
              ),
            ),
            SizedBox(
              width: 300,
              child: ListView.builder(
                itemBuilder: (context, index) => Text('data $index'),
                itemCount: 200,
              ),
            ),
            SizedBox(
              width: 300,
              child: ListView.builder(
                itemBuilder: (context, index) => Text('data $index'),
                itemCount: 200,
              ),
            ),
            SizedBox(
              width: 300,
              child: ListView.builder(itemBuilder: (context, index) => Text('data $index'), itemCount: 200),
            ),
            SizedBox(
              width: 300,
              child: ListView.builder(itemBuilder: (context, index) => Text('data $index'), itemCount: 200),
            ),
          ],
        ),
      )