Expand Widget to fill remaining space in ListView

Viewed 3750

enter image description here

As in the image shown above, I want widget 2 to always be at least the height of the remaining space available.

But widget 2 might contain so many ListTiles so that they can not be displayed without scrolling. But scrolling should affect widget 1 and widget 2. What is the best way to implement something like this?

3 Answers

Wrap Widget 2 in an Expanded Widget.

To scroll both Widget 1 and Widget 2, wrap both of them in a SingleChildScrollView Widget.

If you can distinguish between the case with a few and many elements (for example during loading), you can use CustomScrollView with SliverFillRemaining for this:

  var _isLoading = true;

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: [
        _buildWidget1(),
        _buildWidget2(),
      ],
    );
  }

  Widget _buildWidget1() {
    return SliverToBoxAdapter(
      child: Container(height: 400, color: Colors.blue),
    );
  }

  Widget _buildWidget2() {
    if(_isLoading) {
      return SliverFillRemaining(
        hasScrollBody: false,
        child: Center(child: const CircularProgressIndicator()),
      );
    } else {
      return SliverFixedExtentList(
        delegate: SliverChildBuilderDelegate(
          _buildItem,
          childCount: childCount,
        ),
        itemExtent: 56,
      );
    }
  }

A simple way to do that would be to place your widgets in Column and wrap it with a single child scroll view. For the ListView use shrinkWrap as true and physics you can set to NeverScrollableScrollPhysics

Here is an example

SingleChildScrollView(
  child: Column(
    children: [
      Container(
        height: MediaQuery.of(context).size.height / 2,
        color: Colors.red,
      ),
      ListView.builder(
        shrinkWrap:true,
        physics:NeverScrollableScrollPhysics(),
        itemCount: 100,
        itemBuilder: (context, index) => Text("$index"),
      ),
    ],
  ),
);

Hope this helps!

Related