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