SliverFillRemaining class

A sliver that contains a single box child that fills the remaining space in the viewport.

SliverFillRemaining will size its child to fill the viewport in the cross axis. The extent of the sliver and its child's size in the main axis is computed conditionally, described in further detail below.

Typically this will be the last sliver in a viewport, since (by definition) there is never any room for anything beyond this sliver.

Main Axis Extent

When SliverFillRemaining has a scrollable child

The hasScrollBody flag indicates whether the sliver's child has a scrollable body. This value is never null, and defaults to true. A common example of this use is a NestedScrollView. In this case, the sliver will size its child to fill the maximum available extent.

When SliverFillRemaining does not have a scrollable child

When hasScrollBody is set to false, the child's size is taken into account when considering the extent to which it should fill the space. The precedingScrollExtent of the SliverConstraints is also taken into account in deciding how to layout the sliver.

  • SliverFillRemaining will size its child to fill the viewport in the main axis if that space is larger than the child's extent, and the precedingScrollExtent has not exceeded the main axis extent of the viewport.

In this sample the SliverFillRemaining sizes its child to fill the remaining extent of the viewport in both axes. The icon is centered in the sliver, and would be in any computed extent for the sliver.
Widget build(BuildContext context) {
  return CustomScrollView(
    slivers: <Widget>[
      SliverToBoxAdapter(
        child: Container(
          color: Colors.amber[300],
          height: 150.0,
        ),
      ),
      SliverFillRemaining(
        hasScrollBody: false,
        child: Container(
          color: Colors.blue[100],
          child: Icon(
            Icons.sentiment_very_satisfied,
            size: 75,
            color: Colors.blue[900],
          ),
        ),
      ),
    ],
  );
}

  • SliverFillRemaining will defer to the size of its child if the child's size exceeds the remaining space in the viewport.

In this sample the SliverFillRemaining defers to the size of its child because the child's extent exceeds that of the remaining extent of the viewport's main axis.
Widget build(BuildContext context) {
  return CustomScrollView(
    slivers: <Widget>[
      SliverFixedExtentList(
        itemExtent: 100.0,
        delegate: SliverChildBuilderDelegate(
          (BuildContext context, int index) {
            return Container(
              color: index % 2 == 0
                ? Colors.amber[200]
                : Colors.blue[200],
            );
          },
          childCount: 3,
        ),
      ),
      SliverFillRemaining(
        hasScrollBody: false,
        child: Container(
          color: Colors.orange[300],
          child: Padding(
            padding: const EdgeInsets.all(50.0),
            child: FlutterLogo(size: 100),
          ),
        ),
      ),
    ],
  );
}

  • SliverFillRemaining will defer to the size of its child if the precedingScrollExtent exceeded the length of the viewport's main axis.

In this sample the SliverFillRemaining defers to the size of its child because the precedingScrollExtent of the SliverConstraints has gone beyond that of the viewport's main axis.
Widget build(BuildContext context) {
  return CustomScrollView(
    slivers: <Widget>[
      SliverFixedExtentList(
        itemExtent: 130.0,
        delegate: SliverChildBuilderDelegate(
          (BuildContext context, int index) {
            return Container(
              color: index % 2 == 0
                ? Colors.indigo[200]
                : Colors.orange[200],
            );
          },
          childCount: 5,
        ),
      ),
      SliverFillRemaining(
        hasScrollBody: false,
        child: Container(
          child: Padding(
            padding: const EdgeInsets.all(50.0),
            child: Icon(
              Icons.pan_tool,
              size: 60,
              color: Colors.blueGrey,
            ),
          ),
        ),
      ),
    ],
  );
}

In this sample the SliverFillRemaining's child stretches to fill the overscroll area when fillOverscroll is true. This sample also features a button that is pinned to the bottom of the sliver, regardless of size or overscroll behavior. Try switching fillOverscroll to see the difference.
Widget build(BuildContext context) {
  return CustomScrollView(
    // The ScrollPhysics are overridden here to illustrate the functionality
    // of fillOverscroll on all devices this sample may be run on.
    // fillOverscroll only changes the behavior of your layout when applied
    // to Scrollables that allow for overscroll. BouncingScrollPhysics are
    // one example, which are provided by default on the iOS platform.
    physics: BouncingScrollPhysics(),
    slivers: <Widget>[
      SliverToBoxAdapter(
        child: Container(
          color: Colors.tealAccent[700],
          height: 150.0,
        ),
      ),
      SliverFillRemaining(
        hasScrollBody: false,
        // Switch for different overscroll behavior in your layout.
        // If your ScrollPhysics do not allow for overscroll, setting
        // fillOverscroll to true will have no effect.
        fillOverscroll: true,
        child: Container(
          color: Colors.teal[100],
          child: Align(
            alignment: Alignment.bottomCenter,
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: RaisedButton(
                onPressed: () {
                  /* Place your onPressed code here! */
                },
                child: Text('Bottom Pinned Button!'),
              ),
            ),
          ),
        ),
      ),
    ],
  );
}

See also:

  • SliverFillViewport, which sizes its children based on the size of the viewport, regardless of what else is in the scroll view.
  • SliverList, which shows a list of variable-sized children in a viewport.
Inheritance

Constructors

SliverFillRemaining({Key key, Widget child, bool hasScrollBody: true, bool fillOverscroll: false})
Creates a sliver that fills the remaining space in the viewport.
const

Properties

fillOverscroll bool
Indicates whether the child should stretch to fill the overscroll area created by certain scroll physics, such as iOS' default scroll physics. This value cannot be null. This flag is only relevant when the hasScrollBody value is false. [...]
final
hasScrollBody bool
Indicates whether the child has a scrollable body, this value cannot be null. [...]
final
child Widget
The widget below this widget in the tree. [...]
final, inherited
hashCode int
The hash code for this object. [...]
read-only, inherited
key Key
Controls how one widget replaces another widget in the tree. [...]
final, inherited
runtimeType Type
A representation of the runtime type of the object.
read-only, inherited

Methods

createRenderObject(BuildContext context) RenderSliverFillRemaining
Creates an instance of the RenderObject class that this RenderObjectWidget represents, using the configuration described by this RenderObjectWidget. [...]
override
updateRenderObject(BuildContext context, covariant RenderSliverFillRemaining renderObject) → void
Copies the configuration described by this RenderObjectWidget to the given RenderObject, which will be of the same type as returned by this object's createRenderObject. [...]
override
createElement() SingleChildRenderObjectElement
RenderObjectWidgets always inflate to a RenderObjectElement subclass.
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
@protected, inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node. [...]
inherited
didUnmountRenderObject(covariant RenderObject renderObject) → void
A render object previously associated with this widget has been removed from the tree. The given RenderObject will be of the same type as returned by this object's createRenderObject.
@protected, inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
inherited
toDiagnosticsNode({String name, DiagnosticsTreeStyle style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel: DiagnosticLevel.debug}) String
Returns a string representation of this object.
inherited
toStringDeep({String prefixLineOne: '', String prefixOtherLines, DiagnosticLevel minLevel: DiagnosticLevel.debug}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner: ', ', DiagnosticLevel minLevel: DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(dynamic other) bool
The equality operator. [...]
inherited