Reputation: 8651
When I use a ScrollController in a ListView, it blocks the CupertinoSliverNavigationBar largeTitle from transitioning to a smallTitle. However, if I remove the scrollController, the problem goes away. I think it might be a bug in the Cupertino Library
This code demonstrates the issue:
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}')),
);
}),
),
);
}
Now if I remove the scrollController, the problem is gone:
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}')),
);
}),
),
);
}
Upvotes: 1
Views: 1152
Reputation: 5608
This is an expected behavior since NestedScrollView
is meant to manage the scroll positions of all other child scrolling views:
NestedScrollView class
A scrolling view inside of which can be nested other scrolling views, with their scroll positions being intrinsically linked.
So, you cannot control the positions of its children views with an individual ScrollController
. However, you can provide one for NestedScrollView
to manage all at once.
There is still a way to listen to the scroll events of the inner scroll view besides using ScrollController
. You can have your ListView
inside of NotificationListener
and check the scroll info that it provides.
@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'))),
);
},
),
),
),
);
}
Upvotes: 3