首页 > 解决方案 > Flutter - 带有 CupertinoSliverNavigationBar 的 ScrollController,largeTitle 到 smallTitle 不起作用

问题描述

当我在 ListView 中使用 ScrollController 时,它会阻止 CupertinoSliverNavigationBar largeTitle 转换为 smallTitle。但是,如果我删除滚动控制器,问题就会消失。我认为这可能是库比蒂诺图书馆的一个错误

此代码演示了该问题:

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

标签: flutterflutter-cupertino

解决方案


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

NestedScrollView 类

一个滚动视图,其中可以嵌套其他滚动视图,它们的滚动位置是内在链接的。

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

通知监听器

除了使用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'))),
            );
          },
        ),
      ),
    ),
  );
}

推荐阅读