DEV Community

Luiz Eduardo
Luiz Eduardo

Posted on

Flutter Layout: Build powerful scroll simply

You probably already had problems using scroll within a layout that wasn't the most basic. Maybe you didn't have the technical knowledge and tried to use a simple SingleChildScrollView, or you improvised a code and it worked but when you tried in different screen sizes it broke.

One step ahead you already have more knowledge and now you can write complex screens with the power of slivers. So, do you know that you can have the power of slivers, but simply like using SingleChildScrollView?

Yes, you can. Well, almost simple like it.

Let's contextualize: The power of Slivers

First of all, if you wanna learn deeply about slivers watch episode 12 of the series: "The Boring Flutter Development Show" or read the articles available in the advanced layouts section on website.

In resume, slivers are a lower-lever interface for scrolling in Flutter. Behind other scrollable widgets, like ListView, GridView, SingleChildScrollView, and others, have slivers. With them, you can control every pixel of the scrolling area.

This article isn't about explaining who to use slivers, but it talks about a simple way to improve the use of SingleChildScrollView.

The SliverFillRemaining

By definition is used as the last sliver on the screen or widget, cause as the name says, it fills the remaining space of the viewport. It fills in some different ways depending on the child. I want to show you one way that is simple to understate but is powerful in coding.

Initial example:


I have used android for this example to highlight the scroll. Can you see the difference of SingleChildScrollView? To make your answer easy, see the code below and compare the result after that:

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        brightness: Brightness.dark,
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              const SizedBox(height: 10),
Enter fullscreen mode Exit fullscreen mode


════════ Exception caught by rendering library ══════════════
RenderBox was not laid out: RenderFlex#f73ea relayoutBoundary=up12 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
Failed assertion: line 1930 pos 12: 'hasSize'

The relevant error-causing widget was
Enter fullscreen mode Exit fullscreen mode

What it's happening?

The SliverFillRemaining has conditionals build modes, if the size of widgets is bigger than the remaining space in the viewport, it'll "ask" the size of its child (in this case "of its children", because the column is just to compile more than one child in a single one) and render in this size. But if the available space is bigger, it'll inform the size of its child. Therefore, the SliverFillRemaining always has a defined size.

This means, in the example app, that all children below the Column know their size. Thus, we could use another Expanded inside of the Card to set a text at the bottom of the card.

See what happen when the child size is bigger than the viewport size:

Example with big child

In another way, SingleChildScrollView doesn't define the size by itself. If the children don't have a defined size, it cannot set where paint the widgets.


You can wrap the tree: CustomScrollView - SliverFillRemaining - Column in a single widget for an easily use


We saw that SliverFillRemaining is powerful in render and has an easylly approach like SingleChildScrollView. Maybe you can consider using it from now on.

If you saw something, in the article to fix or to improve, please leave a comment below. Happy coding!

What's next?

Do you now how to use the material design search bar in flutter? If don't, read my other article: Search Bar in flutter

Discussion (0)