flutterdart

SliverFillRemaining too large when not the last sliver in CustomScrollView


I'm using a CustomScrollView which contains an element of fixed size and a SliverFillRemaining. If the fixed size element is smaller than the scroll view, I want the SliverFillRemaining element to take up exactly the left over space, so you cannot scroll the scroll view. This works fine if the SliverFillRemaining widget is the last sliver:

CustomScrollView(
  physics: const ClampingScrollPhysics(),
  slivers: [
    SliverToBoxAdapter(
      child: const Placeholder(
        fallbackHeight: 250,
      ),
    ),
    SliverFillRemaining(
      hasScrollBody: false,
      child: Container(
        color: Colors.green,
      ),
    ),
)

CustomScrollView with SliverFillRemaining as the last sliver

However I need the remaining space to be filled at the top. Reversing the order of the slivers results in the SliverFillRemaining having exactly the same height as the CustomScrollView, no matter the other slivers' dimension.

CustomScrollView with SliverFillRemaining as the first sliver

This is not a duplicate question, as the answers on other questions like "Why is SliverFillRemaining expanding too much?" did not solve my problems, neither did using the sliver_fill_remaining_box_adapter package.


Solution

  • SliverFillRemaining is designed to calculate the remaining space below it in the scroll hierarchy. To invert this behavior and have it behave like a top-filling widget, reverse the axis direction of the CustomScrollView using reverse: true. Then, you'll order your slivers accordingly.

    Here's the solution:

    CustomScrollView(
      reverse: true, // Reverse the scroll view direction.
      physics: const ClampingScrollPhysics(),
      slivers: [
        SliverToBoxAdapter(
          child: const Placeholder(
            fallbackHeight: 250,
          ),
        ),
        SliverFillRemaining(
          hasScrollBody: false,
          child: Container(
            color: Colors.green,
          ),
        ),
      ],
    )
    

    I hope this solution resolves your issue.