Peter R
Peter R

Reputation: 3516

Expanded ListView not working inside of TabBarView

Here's a picture of what I'm trying to acheive.

enter image description here

However I want both lists in the TabBarView to expand to the bottom of the screen. The only way I can get it to work now, is with a Container with a fixed height. If I use MediaQuery.of(context).size.height, then it expands off the bottom of the page and I get the yellow black overflow thing.

If I wrap the TabBarView in an Expanded widget instead of the fixed size Container, I get a RenderFlex children have non-zero flex but incoming height constraints are unbounded. error. If I wrap each ListView in Expanded (while the fixed height Container is removed), I get a Horizontal viewport was given unbounded height. error. Any idea what I should try next?

Here's the code.

Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              alignment: Alignment.centerLeft,
              margin: const EdgeInsets.only(bottom: 15, top: 6),
              padding: const EdgeInsets.only(left: 15),
              child: const Text('Home'),
            ),
            DefaultTabController(
              length: 2,
              initialIndex: 0,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Container(
                    child: TabBar(
                      isScrollable: true,
                      tabs: [
                        Tab(text: 'Subscriptions'),
                        Tab(text: 'Recently Visited'),
                      ],
                    ),
                  ),
                  Container(
                    height: 500,
                    decoration: BoxDecoration(
                        border: Border(
                            top: BorderSide(color: Colors.grey, width: 0.5))),
                    child: TabBarView(
                      children: <Widget>[
                        buildAList(),
                        buildAList()
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget buildAList() {
    return ListView(
      scrollDirection: Axis.vertical,
      shrinkWrap: true,
      children: List<Widget>.generate(
        100,
        (i) => Text(
          'Item $i',
          style: TextStyle(fontSize: 20),
        ),
      ).toList(),
    );
  }

Upvotes: 0

Views: 1366

Answers (1)

Benjamin
Benjamin

Reputation: 6171

All I changed in the code below is I wrapped your TabBarView's Container widget with an Expanded widget and then wrapped the DefaultTabController with another Expanded widget. If you're going to put an Expanded widget somewhere, you should probably wrap it's parent with an Expanded widget too if it's inside of a flexible widget such as a Row or Column.

I also changed your buildAList function to use a ListView.builder so that you didn't have to "generate" a list.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              alignment: Alignment.centerLeft,
              margin: const EdgeInsets.only(bottom: 15, top: 6),
              padding: const EdgeInsets.only(left: 15),
              child: const Text('Home'),
            ),
            Expanded(
              child: DefaultTabController(
                length: 2,
                initialIndex: 0,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Container(
                      child: TabBar(
                        isScrollable: true,
                        tabs: [
                          Tab(text: 'Subscriptions'),
                          Tab(text: 'Recently Visited'),
                        ],
                      ),
                    ),
                    Expanded(
                      child: Container(
                        decoration: BoxDecoration(
                          border: Border(
                            top: BorderSide(color: Colors.grey, width: 0.5),
                          ),
                        ),
                        child: TabBarView(
                          children: <Widget>[
                            buildAList(),
                            buildAList(),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget buildAList() {
    return ListView.builder(
      shrinkWrap: true,
      itemCount: 100,
      itemBuilder: (c, i) {
        return Text(
          "Item $i",
          style: TextStyle(fontSize: 20),
        );
      },
    );
  }

Upvotes: 2

Related Questions