底部滚动页脚的Listview [英] Listview with scrolling Footer at the bottom

查看:117
本文介绍了底部滚动页脚的Listview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个滚动列表小部件,该部件需要显示一些项目,并能够在底部滚动添加页脚。

I'm trying to create a scrolling list widgets which takes displays a few items and has the ability to add a footer at the bottom which scrolls along.

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

If the scrolling list doesn't take up the complete height, e.g. there are only 2 items, the footer should still appear at the bottom of the screen. Here are some sketches of what I'm trying to achieve


我尝试计算列表视图所需的垂直大小,但这意味着我需要在生成时知道孩子的身高。有没有更好的办法?

I tried calculating the vertical size that the listview needs but that'd mean that I need the know the height of the children at build time. Is there a better way?

编辑

我正在尝试实现与此处,但当然会有Flutter。

EDIT
I'm trying to achieve the exact same thing as here but with Flutter of course.

推荐答案

您将需要为此创建一个自定义RenderBox。由于没有开箱即用的小部件。

You will need to create a custom RenderBox for this. As there's no widgets which supports this out of the box.

SliverFillRemaining 非常接近。但是调整大小/滚动行为与您期望的不同。因为,如果存在,它将几乎总是使 Scrollable ...可滚动。

SliverFillRemaining comes pretty close. But it's sizing/scrolling behavior is different then what you'd expect. As, if present, will almost always make the Scrollable... scrollable.

相反,我们可以复制粘贴 SliverFillRemaining 的来源。并进行一些修改

Instead, we can copy paste the sources of SliverFillRemaining. And make some edits

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);
    }
  }
}






我在这里更改了3项


Here I changed one 3 things


  • 孩子不受约束 maxExtent 。因为如果没有更多的屏幕空间,则会将页脚高度设置为0。

  • 更改了 SliverGeometry scrollExtent 从全屏高度到实际可用大小。这样实际上它只能填充剩余的可见空间。不填满屏幕。

  • 为相同的 scrollExtent 添加了一个最小值,等于实际的页脚高度。因此,如果视口中没有剩余空间,则可以简单地添加子代,而在子代周围没有任何间距。

  • Unconstrained the child maxExtent. Because if there's no more screen-space available, that would enforce a height of 0 to the footer.
  • changed SliverGeometry scrollExtent from "full screen height" to "actual available size". So that it actually only fill the remaining visible space. Not fill the screen.
  • added a minimum value to that same scrollExtent, equal to the actual footer height. So that if there's no more space remaining in the viewport, the children is simply added without any spacing around it.

我们现在可以使用像往常一样放在我们的 CustomScrollView 内。

We can now use it inside our CustomScrollView as usual.

最终结果:

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,
        ),
      ),
    ),
  ],
),

这篇关于底部滚动页脚的Listview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆