2

我创建了一个自定义小部件,将页脚作为最后一项添加到收到的可滚动小部件中。一切正常,但我想更改创建页脚的时间。

就像ListView.builder在滚动到屏幕上时创建项目一样,我也希望在页脚中发生这种情况。如果此自定义小部件收到一个ListView.builderor GridView.builder,则它们的项目在滚动到屏幕上时会被很好地创建,但页脚是第一次创建的,即使它不在屏幕上也是如此。

这是自定义小部件,其中接收到的小部件是widget.child( ScrollView),页脚是widget.footer( Widget)。

@override
Widget build(BuildContext context) {
  return Scrollable(
    controller: widget.child.controller,
    axisDirection: widget.child.getDirection(context),
    viewportBuilder: (context, offset) {
      return ShrinkWrappingViewport(
        axisDirection: widget.child.getDirection(context),
        offset: offset,
        slivers: widget.child.buildSlivers(context)
          ..add(
              SliverList(
                  delegate: SliverChildBuilderDelegate((context, index) {
            print('footer');
            return widget.footer;
          }, childCount: 1))),
      );
    },
  );
}

这就是我使用它的方式:

ScrollableWithFooter(
  child: ListView.builder(
    itemCount: 50,
    itemBuilder: (context, index) {
      print(index);
      return SizedBox(height: 400, child: Text('Item $index'));
    },
  ),
  footer: Center(child: Text('Footer')),
)

有 50 个列表,我看到屏幕上的第一个项目,这是打印的输出:

I/flutter (28472): 0
I/flutter (28472): 1
I/flutter (28472): 2
I/flutter (28472): footer

当我开始滚动时,其他项目在创建时开始打印它们的索引:

I/flutter (28472): 2
I/flutter (28472): footer
I/flutter (28472): 3
I/flutter (28472): 4
I/flutter (28472): 5

这适用于项目,但不适用于页脚。我希望在到达列表末尾时创建页脚,就像其他项目一样。怎样才能做到这一点?

请注意,在屏幕上一切正常,页脚出现在列表的末尾。只是它的创造发生在它应该发生之前。


这是我尝试过的,但它不起作用:

@override
Widget build(BuildContext context) {
  return Scrollable(
    controller: widget.child.controller,
    axisDirection: widget.child.getDirection(context),
    viewportBuilder: (context, offset) {
      List<Widget> slivers = widget.child.buildSlivers(context);
      return ShrinkWrappingViewport(
        axisDirection: widget.child.getDirection(context),
        offset: offset,
        slivers: [
          SliverList(
              delegate: SliverChildBuilderDelegate((context, index) {
            if (index < slivers.length) {
              return slivers[index]; // <- Here seems to be the problem
            }
            print('footer');
            return widget.footer;
          }, childCount: slivers.length + 1))
        ],
      );
    },
  );
}

我收到此错误:

The following assertion was thrown building NotificationListener<KeepAliveNotification>:
I/flutter (28472): A RenderRepaintBoundary expected a child of type RenderBox but received a child of type
I/flutter (28472): RenderSliverPadding.
4

2 回答 2

0

我找到了一种方法来做到这一点。我做得很好,问题是由于某种原因SliverChildBuilderDelegate总是创建前 2 个元素,即使它们没有滚动到屏幕上。所以我必须创建 2 个虚拟的不可见页脚,然后创建真正的页脚,这样当滚动到屏幕上时,将创建真正的页脚:

@override
Widget build(BuildContext context) {
return Scrollable(
  controller: widget.child.controller,
  axisDirection: widget.child.getDirection(context),
  viewportBuilder: (context, offset) {
    return ShrinkWrappingViewport(
      axisDirection: widget.child.getDirection(context),
      offset: offset,
      slivers: widget.child.buildSlivers(context)
        ..add(SliverList(
            delegate: SliverChildBuilderDelegate((context, index) {
          if (index < 2) {
            print('dummy footer');
            return SizedBox.shrink();
          }
          print('footer');
          return widget.footer;
        }, childCount: 3))),
    );
  },
);

这将是没有打印的最终解决方案:

@override
Widget build(BuildContext context) {
  return Scrollable(
    controller: widget.child.controller,
    axisDirection: widget.child.getDirection(context),
    viewportBuilder: (context, offset) {
      return ShrinkWrappingViewport(
        axisDirection: widget.child.getDirection(context),
        offset: offset,
        slivers: widget.child.buildSlivers(context)
          ..add(SliverList(
              delegate: SliverChildBuilderDelegate(
                  (_, index) => index < 2 ? SizedBox.shrink() : widget.footer,
                  childCount: 3))),
      );
    },
  );
}

现在,自定义小部件有效地在任何滚动视图的底部添加了页脚,仅当滚动视图的项目和页脚滚动到屏幕上时才会创建它们。

如果有人找到更好的方法来做到这一点,请告诉我。目前,我对这个解决方案没有意见。

于 2019-11-02T08:55:38.650 回答
0

您可以向列表视图的控制器添加一个侦听器,它将侦听滚动,当您到达底部时,您将激活一些称为页脚的标志,然后显示页脚

于 2019-10-28T12:30:34.513 回答