36

I want my screen to be scrollable so I put everything in a Listview.

Now I want to show another Listview inside to show details of a List. When I try this an error is thrown - " Expanded widgets must be placed inside Flex widgets."

enter image description here

2
  • 2
    Add shrinkwrap: true in listview.builder Commented Nov 25, 2018 at 7:15
  • Remove the top most container or replace it with column Commented Nov 25, 2018 at 7:54

8 Answers 8

74

Add shrinkWrap: true in listView.builder & Remove the top most Container or replace it with Column.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you, this was particularly helpful for placing a listview.builder inside a listView but without the usage of Expanded...
note that this will render all of the widgets that inner list contains, meaning it will cause problems with infinite lists or very big ones
57

Adding shrinkWrap: true, physics: ScrollPhysics(), inside the listview.builder, in this case the listview.builder need an expanded parent. The physics: ScrollPhysics() will allow it to maintain its state without scrolling back to the first items. Also, you can use physics: NeverScrollableScrollPhysics(), if you don't want the listview.builder to be scrolled by the user.

1 Comment

Great! Thanks @CodeMemory, it works perfectly for ListView.builder with dynamics data.
15

I want my screen to be scrollable so I put everything in a Listview.

I think you should use a CustomScrollView with slivers instead.

If it's the first time your hear about slivers, or if they seem a little bit scary, I suggest you to read this excellent article written by Emily Fortuna.

In your case, I would do something like this:

return CustomScrollView(
  slivers: <Widget>[
    SliverToBoxAdapter(
      // Put here all widgets that are not slivers.
      child: Container(),
    ),
    // Replace your ListView.builder with this:
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return ListTile();
        },
      ),
    ),
  ],
);

Comments

9

I had this issue when I used two ListViews, one inside another. Nothing has worked for me except this workaround.

In the nested Listview, cover it with a ConstrainedBox and give it some large height. and use 'shrinkWrap: true' both ListViews. Since the shrinkwrap will trim the extra space, that extra height won't be an issue.

Flexible(
  child: ListView(
    children: <Widget>[
      //other Widgets here ...
      ConstrainedBox(
        constraints: BoxConstraints(maxHeight: 1000), // **THIS is the important part**
        child: ListView.builder(
          shrinkWrap: true,
          itemBuilder: (context, index) => _buildRow(index),
          itemCount: _elements.length,
        ),
      ),
    ],
  ),
),

Comments

8

In my case, adding physics: ScrollPhysics(), in the ListView.builder made the ListView.builder scrollable.

The hierarchy was ListView > StreamBuilder > RefreshIndicator > ListView.builder .

Comments

7

It actually depends on your layout. Possible cases could be:

  • Using ListView + ListView:

    If you want to give your second ListView full height.

    ListView(
      children: [
        // Your other widgets ...
        ListView.builder(
          shrinkWrap: true, //    <-- Set this to true
          physics: ScrollPhysics(), // <-- Also change physics
          itemBuilder: ...,
        ),
      ],
    )
    
  • Using ListView + ListView:

    If you want to limit the height of your second ListView.

    ListView(
      children: [
        // Your other widgets ...
        SizedBox( //             <-- Use SizedBox
          height: 160, 
          child: ListView.builder(
            itemBuilder: ...,
          ),
        ),
        // Your other widgets ...
      ],
    )
    
  • Using Column + ListView:

    If you don't have too many (or too big) children in your first ListView, replace it with a Column.

    Column(
      children: [
        // Your other widgets ...
        Expanded( //              <-- Use Expanded
          child: ListView.builder(
            itemBuilder: ...,
          ),
        ),
      ],
    )
    

Comments

4

I was able to solve the problem by wrapping main column inside a SingleChildScrollView, then wrapping the ListView.builder inside a Container giving container a specified height, and then wrapping that container inside a SingleChildScrollView again. I know it's a but complex, but it worked for me! you can have a clear picture by the code.

 Scaffold(
    appBar: AppBar(
      centerTitle: true,
      backgroundColor: Colors.black,
      title: Text("Welcome, ${widget.myUser.name}"),
      actions: [
        InkWell(
          child: Container(
            alignment: Alignment.center,
            padding: EdgeInsets.only(right: 20),
            child: Icon(Icons.settings),
          ),
          onTap: () {},
        ),
      ],
    ),
    body: Padding(
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: [
            _customerDetailsWidget(),
            SizedBox(
              height: 15,
            ),
            Container(
              child: Divider(
                color: Colors.grey[500],
              ),
            ),
            SizedBox(
              height: 15,
            ),
            _addProductText(),
            SingleChildScrollView(
                child: Container(
                  height: 500,
                  child: ListView.builder(
                    itemCount:1,
                    itemBuilder: (BuildContext context, int index) {
                      return Container(child: Text("HELLO WORLD"));
                    },
                  ),
                ))
          ],
        ),
      ),
    ),
  ),

1 Comment

Thank you. I additional add SingleChildScrollView in ListView.build set shrinkWrap value to true.
0
ListView.builder(
  physics: ScrollPhysics(),

  itemCount: question.questionByPage.value.data.length,

  shrinkWrap: true,

  primary: false,

  itemBuilder: (context, index) => ListView.builder(

    physics: ScrollPhysics(),

    shrinkWrap: true,

    itemCount: question.questionByPage.value

        .data[index].questions.length,

    itemBuilder: (BuildContext context, int qIndex) {

      var mydata = question.questionByPage.value

          .data[index].questions[qIndex];

      return ListView.builder(

        physics: ScrollPhysics(),

        shrinkWrap: true,

        itemCount: mydata.options.length,

        itemBuilder: (BuildContext context, int oIndex) {

          var option = mydata.options[oIndex];

          return Column(
       
            crossAxisAlignment: CrossAxisAlignment.start,

            children: [
           

              Text(
                mydata.description.toString(),

                textAlign: TextAlign.left,

              ),
              Text(

                option.optionText.toString(),

                textAlign: TextAlign.left,
              ),

            ],
          );
        },
      );
    },
  ),
),

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.