dart - 底部带有滚动页脚的 ListView

我正在尝试创建一个滚动列表小部件,它可以显示一些项目,并且能够在底部添加一个可滚动的页脚。

如果滚动列表没有占据整个高度,例如只有 2 个项目,页脚仍应出现在屏幕底部。以下是我正在努力实现的一些草图

我尝试计算 ListView 所需的垂直大小,但这意味着我需要在构建时知道子项的高度。有没有更好的办法?

编辑
我正在尝试实现与 here 完全相同的目标但当然是 Flutter。

最佳答案

您需要为此创建一个自定义 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 从“全屏高度”更改为“实际可用尺寸”。这样它实际上只填充剩余的可见空间。不填满屏幕。
  • 为相同的 scrollExtent 添加了一个最小值,等于实际的页脚高度。因此,如果视口(viewport)中没有剩余空间,则会简单地添加子项,而其周围没有任何间距。

我们现在可以像往常一样在 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,
        ),
      ),
    ),
  ],
),

https://stackoverflow.com/questions/49620212/

相关文章:

flutter - 如何在等待来自后端 API 的数据时最初显示 RefreshIndicator?

dart - 如何检查 Flutter Text 小部件是否溢出

flutter - 具有水平、未填充子项的 PageView

android-studio - flutter Android Studio : Error re

firebase - 无法为 flutter 构建发布 APK

android - 如何从 Flutter App 连接 Ms SQL?

dart - 在小部件树中使用 const 会提高性能吗?

dart - 回复 : create a dropdown button in flutter

dart - Flutter 删除目录文件

dart - Flutter:使用 SlideTransition