您需要为此创建一个自定义RenderBox.因为没有开箱即用的小部件来支持这一点.
SliverFillRemaining
已经非常接近了.但它的大小调整/滚动行为与您预期的不同.就像,如果有的话,几乎总是会让Scrollable
…可滚动的.
取而代之的是,我们可以复制粘贴SliverFillRemaining
个源码.并做一些编辑
class SliverFooter extends SingleChildRenderObjectWidget {
/// Creates a sliver that fills the remaining space in the viewport.
const SliverFooter({
Key key,
Widget child,
}) : super(key: key, child: child);
@override
RenderSliverFooter createRenderObject(BuildContext context) => new RenderSliverFooter();
}
class RenderSliverFooter extends RenderSliverSingleBoxAdapter {
/// Creates a [RenderSliver] that wraps a [RenderBox] which is sized to fit
/// the remaining space in the viewport.
RenderSliverFooter({
RenderBox child,
}) : super(child: child);
@override
void performLayout() {
final extent = constraints.remainingPaintExtent - math.min(constraints.overlap, 0.0);
var childGrowthSize = .0; // added
if (child != null) {
// changed maxExtent from 'extent' to double.infinity
child.layout(constraints.asBoxConstraints(minExtent: extent, maxExtent: double.infinity), parentUsesSize: true);
childGrowthSize = constraints.axis == Axis.vertical ? child.size.height : child.size.width; // added
}
final paintedChildSize = calculatePaintOffset(constraints, from: 0.0, to: extent);
assert(paintedChildSize.isFinite);
assert(paintedChildSize >= 0.0);
geometry = new SliverGeometry(
// used to be this : scrollExtent: constraints.viewportMainAxisExtent,
scrollExtent: math.max(extent, childGrowthSize),
paintExtent: paintedChildSize,
maxPaintExtent: paintedChildSize,
hasVisualOverflow: extent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0,
);
if (child != null) {
setChildParentData(child, constraints, geometry);
}
}
}
在这里我改变了一件三件事
maxExtent
.因为如果没有更多的屏幕空间可用,将强制页脚高度为0.SliverGeometry
scrollExtent
从"全屏高度"更改为"实际可用大小".所以它实际上只剩下fill个可见空间.而不是填满屏幕.scrollExtent
,等于实际页脚高度.因此,如果视口中没有剩余空间,只需添加子对象,而不在其周围留有任何间距.我们现在可以像往常一样在我们的CustomScrollView
内使用它.
最终结果:
new CustomScrollView(
slivers: <Widget>[
new SliverFixedExtentList(
itemExtent: 42.0,
delegate: new SliverChildBuilderDelegate((context, index) {
return new SizedBox.expand(
child: new Card(),
);
}, childCount: 42),
),
new SliverFooter(
child: new Align(
alignment: Alignment.bottomCenter,
child: new Container(
height: 42.0,
color: Colors.red,
),
),
),
],
),