Flutter ListView doesn't get constrained by wrapping it in Expanded

Issue

I’m struggling hard with Flutter’s sizing constraints.

I’m trying to make a custom scaffold like screen with a custom appbar and a stack below it with the lowest layer being a listview, and then maybe floating buttons on top if that.

I can’t figure out what the proper solution would be to make the listview not throw "vertical viewport was given unbounded height" error.

Here’s my code:

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:my/model.dart';
import 'package:my/widgets/menucard.dart';
import 'package:my/screens/my1.dart';
import 'package:my/screens/my2.dart';
import 'package:my/screens/my3.dart';
import 'package:my/provider.dart';

class myAppBar extends StatelessWidget {
  myAppBar(
      {super.key,
      required double height,
      required String title,
      bool autoImplyBack = true})
      : _height = height,
        _title = title,
        _autoback = autoImplyBack;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: _height,
      color: Colors.pink,
      child: SizedBox(
        width: double.infinity,
        height: _height,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            SizedBox(
              width: _height,
              height: _height,
              child: Navigator.canPop(context) && _autoback
                  ? IconButton(
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      icon: Icon(Icons.arrow_back),
                    )
                  : null,
            ),
            Center(
              child: Text(_title),
            ),
            SizedBox(
              width: _height,
              height: _height,
              child: IconButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                icon: Icon(Icons.close),
              ),
            ),
          ],
        ),
      ),
    );
  }

  double _height;
  String _title;
  bool _autoback;
}

class myMenu extends StatelessWidget {
  const myMenu({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          myAppBar(height: 100, title: 'Menu'),
          Container(
            color: Colors.teal,
            child: Expanded(
              child: //Stack(
                  //children: [
                  ListView(
                children: [
                  MenuCard(
                      icondata: Icons.circle,
                      subMenu: 'my1',
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const my1()),
                        );
                      }),
                  MenuCard(
                      icondata: Icons.circle,
                      subMenu: 'my2',
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const my2()),
                        );
                      }),
                  MenuCard(
                      icondata: Icons.circle,
                      subMenu: 'my3',
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const my3()),
                        );
                      }),
                  MenuCard(
                      icondata: Icons.circle,
                      subMenu: 'log out',
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const my1()),
                        );
                      }),
                ],
              ),
              //],
            ),
          ),
          //),
        ],
      ),
    );
  }
}

I’ve tried setting the listview’s shrinkwrap property to true, but that turned out to be ugly as well as not so much performant according to other threads regarding this topic.

I’ve also tried wrapping the listview in Expanded and Flexible, but to no avail.

Solution

You can shift the Expanded widget on top of Container.

body: Column(
  children: [
    myAppBar(height: 100, title: 'Menu'),
    Expanded(
      child: Container(

Also while you are trying to create custom AppBar, you can implements PreferredSizeWidget

class myAppBar extends StatelessWidget implements PreferredSizeWidget {
  .... //get height using constructor.
  @override
  Widget build(BuildContext context) {
    return Container(height:);
  }

  @override
 Size get preferredSize => Size.fromHeight(height);
}

Answered By – Yeasin Sheikh

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.