How to make a horizontal ListView in flutter take as much height as its children max height, placed in a column?

Issue

I have a horizontal ListView placed in a column, and I want it to have as much height as it only needs. One way to do this is to wrap the ListView in a SizedBox and give it a specific hardcoded height. Also, wrapping it in an Expanded widget will cause the ListView take the additional available space in the column. But, I want it to take as much height as it only needs, automatically.
How can this be achieved? Thank you.

The sample code is as follows:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            children: [
              Text("Hi there!"),
              SizedBox(
                height: 50,
                child: ListView(
                  scrollDirection: Axis.horizontal,
                  shrinkWrap: true,
                  children: List.generate(
                    4,
                    (index) => Text("Item $index "),
                  ),
                ),
              ),
              ElevatedButton(
                onPressed: () {},
                child: Text("This is a button"),
              ),
            ],
          ),
        ),
      ),
    );
  }

The output is:
enter image description here

But what I want (no more or less space around the ListView):
enter image description here

Solution

Unfortunately this is not possible. A ListView could potentially have a lot of items (or even unlimited), so figuring out "the biggest one" requires going through each item, which is against the whole point of using a ListView.

If you only have a few items, you can use Row widget instead. If you need scrolling, wrap Row with a SingleChildScrollView.

For example:

Column(
  children: [
    Container(
      color: Colors.green.shade100,
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: [
            FlutterLogo(),
            FlutterLogo(size: 100),
            for (int i = 0; i < 50; i++) FlutterLogo(),
          ],
        ),
      ),
    ),
    const Text('The row has ended.'),
  ],
)

Demo:

demo gif

Answered By – user1032613

Answer Checked By – Marilyn (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *