Flutter - 带有 CupertinoSliverNavigationBar 的 ScrollController,从 largeTitle 到 smallTitle 不工作

Flutter - ScrollController with CupertinoSliverNavigationBar, largeTitle to smallTitle not working

当我在 ListView 中使用 ScrollController 时,它会阻止 CupertinoSliverNavigationBar largeTitle 转换为 smallTitle。但是,如果我删除 scrollController,问题就会消失。我认为这可能是 Cupertino 库中的一个错误

这段代码演示了这个问题:

 ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            CupertinoSliverNavigationBar(
              largeTitle: Text('Large Title'),
            ),
          ];
        },
        body: ListView.builder(
            controller: scrollController,
            itemCount: 50,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                height: 50,
                child: Center(child: Text('Entry ${index}')),
              );
            }),
      ),
    );
  }

现在,如果我删除 scrollController,问题就消失了:

ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            CupertinoSliverNavigationBar(
              largeTitle: Text('Large Title'),
            ),
          ];
        },
        body: ListView.builder(
            //controller: scrollController,
            itemCount: 50,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                height: 50,
                child: Center(child: Text('Entry ${index}')),
              );
            }),
      ),
    );
  }

这是预期的行为,因为 NestedScrollView 旨在管理所有其他子滚动视图的滚动位置:

NestedScrollView class

A scrolling view inside of which can be nested other scrolling views, with their scroll positions being intrinsically linked.

因此,您无法通过个人 ScrollController 控制其子视图的位置。但是,您可以为 NestedScrollView 提供一个以一次性管理所有。

NotificationListener

除了使用ScrollController之外,还有一种方法可以监听内部滚动视图的滚动事件。您可以将 ListView 放在 NotificationListener 中并检查它提供的滚动信息。

@override
Widget build(BuildContext context) {
  return CupertinoPageScaffold(
    child: NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          CupertinoSliverNavigationBar(
            largeTitle: Text('Large Title'),
          ),
        ];
      },
      body: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification scrollInfo) {
          if (scrollInfo.metrics.pixels ==
              scrollInfo.metrics.maxScrollExtent) {
            print('Reached the bottom');
          }
          return;
        },
        child: ListView.builder(
          itemCount: 50,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              height: 50,
              child: Center(child: Material(child: Text('Entry $index'))),
            );
          },
        ),
      ),
    ),
  );
}