Search code examples
flutterdartuser-interfacestate-managementflutter-bloc

Why empty Container take full height of the screen in flutter?


Edit:

Question: Why does some Container in flutter take full height of the screen, where as other doesn't ?

Let me illustrate:

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("This is Text 1"),
            Container(), // 👈 This doesn't take full height of the screen
            Text("This is Text 2 ")
          ],
        )
            // bottomNavigationBar: Container(), // 👈 Where as this take
            ));
  }

This is seemingly strange, and is there specific explanation for this ?

Answer:

For the Container not to take the complete height replace it with SizedBox.shrink()


Original Question:

I came across this strange error, Which I am witnessing first time, and have no clue of its occurrence.

body: Text("Hello"),
bottomNavigationBar: BlocBuilder<UserCubit, UserState>(
        builder: (context, state) {
          if (state.userModel?.cartTotalDiscountedPrice != 0) {
            return Material(...);
          }
          return Container();
        },

The problem is when the value of state.userModel?.cartTotalDiscountedPrice is 0, the body is not displayed, here hello is not displayed.

How does the BlocBuilder of bottomNavigationBar affecting the body ?


Output:

When state.userModel?.cartTotalDiscountedPrice != 0

enter image description here

When state.userModel?.cartTotalDiscountedPrice == 0

enter image description here


Solution

  • I think this is not an issue with BlocBuilder. This can be reproduced with below code:

    class Demo extends StatelessWidget {
      const Demo({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: const Text('Demo Cart'),
            ),
            body: const Center(child: Text('Hello')),
            bottomNavigationBar: Container());
      }
    }
    

    Having a container or any other widget without size causing Scaffold body to shift above.

    Containers with no children try to be as big as possible unless the incoming constraints are unbounded, in which case they try to be as small as possible.

    You can use SizedBox.shrink() if you need empty space.

    UPDATE:

    Summary: Container tries, in order: to honor alignment, to size itself to the child, to honor the width, height, and constraints, to expand to fit the parent, to be as small as possible.

    More specifically:

    If the widget has no child, no height, no width, no constraints, and the parent provides unbounded constraints, then Container tries to size as small as possible.

    If the widget has no child and no alignment, but a height, width, or constraints are provided, then the Container tries to be as small as possible given the combination of those constraints and the parent's constraints.

    If the widget has no child, no height, no width, no constraints, and no alignment, but the parent provides bounded constraints, then Container expands to fit the constraints provided by the parent.

    If the widget has an alignment, and the parent provides unbounded constraints, then the Container tries to size itself around the child.

    If the widget has an alignment, and the parent provides bounded constraints, then the Container tries to expand to fit the parent, and then positions the child within itself as per the alignment.

    Otherwise, the widget has a child but no height, no width, no constraints, and no alignment, and the Container passes the constraints from the parent to the child and sizes itself to match the child.

    More about Container class