'Flutter How to change container height based on the ListView's item height?

Hello I have a Scaffold wrapped with SingleChildScrollView and child is Column. Inside Column; Container, TabBar and TabBarView.

First Container is just there for black space.

Container(
                    color: Colors.black,
                    height: 300,
                  ),

The second widget of Column which mean TabBar: (I know we can use it in AppBar but now it is what it is.)

 const TabBar(
                    labelColor: Colors.red,
                    tabs: [
                      Tab(text: "Tab1"),
                      Tab(text: "Tab2"),
                      Tab(text: "Tab3"),
                    ],
                  ),

Last Column widget is TabBarView. It wrapped by Container that has 300 height.

 Container(
                    height: 300, // here is problem
                    color: Colors.amber,
                    child: TabBarView(
                      children: [
                        buildContainer(200, Colors.red, 2),
                        buildContainer(100, Colors.red, 2),
                        buildContainer(150, Colors.red, 3),
                      ],
                    ),
                  ),

and also this is buildContainer method;

buildContainer(double height, Color color, int count) => ListView.builder(
      shrinkWrap: true,
      itemCount: count,
      itemBuilder: (BuildContext context, int index) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Container(
            height: height,
            color: color,
            child: Center(
              child: Text("my height ${height.toString()}"),
            ),
          ),
        );
      });

enter image description here

Here is my question. I have 3 tabs and I have three ListViewBuilder.Each one has own child count. But all of them height limited to 300 because of their parent that is Container. I want to set Tab's height dynamicly with each ListViewBuilder's item count. How can I do that ? I accept dynamic height without child scrolling. I mean, I can scroll whole page for reach the last child. In example, Instagram profile tab. If I have 30 photo, height is phone height. But I have 300 photo, it scrolling all the way down. But also, I don't want to understand pagenation for this one. I am not going to do Instagram. I just want to that, If I create 5 container, okey show me your max height. If I create 1 container, show me just that without scrolling.



Solution 1:[1]

I added a dynamic height calculation depending on the number of objects in the ListView.builder. The formula is not perfect, you can add to it, but the point is to subtract the AppBar height and padding to get a clean screen area that the widget completely occupies.

import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: mainWidget(),
        );
      }
    
      Widget mainWidget() {
        AppBar appBar = AppBar(
          toolbarHeight: 56, //You can manually set the AppBar height
          title: const Text("App bar"),
        );
        print(appBar.preferredSize); // Or you can save this value and use it later, it will not be fixed, but will depend on the screen size
        return Scaffold(
          appBar: appBar,
          body: HelpSO(color: Colors.red, count: 5),
        );
      }
    }
    
    class HelpSO extends StatelessWidget {
      late double height;
      Color color;
      int count;
    
      HelpSO({Key? key, required this.color, required this.count})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        // height = (deviceHeight / itemCount) - padding (top + bottom) - appbar.prefferedSize.height / 2;
        height = (MediaQuery.of(context).size.height / count) - 16.0 - 56 / 2;
    
        return ListView.builder(
            shrinkWrap: true,
            itemCount: count,
            itemBuilder: (BuildContext context, int index) {
              return Padding(
                padding: const EdgeInsets.all(8.0), // Subtract this value
                child: Container(
                  height: height,
                  color: color,
                  child: Center(
                    child: Text("My height ${height.toString()}"),
                  ),
                ),
              );
            });
      }
    }

A picture that shows the use of 1, 3 and 5 widgets.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1