CustomScrollView scroll behavior changes when scrollController is passed
I think you may notice the explanation of the example here: NestedScrollView class
// The "controller" and "primary" members should be left
// unset, so that the NestedScrollView can control this
// inner scroll view.
// If the "controller" property is set, then this scroll
// view will not be associated with the NestedScrollView.
// The PageStorageKey should be unique to this ScrollView;
// it allows the list to remember its scroll position when
// the tab view is not on the screen.
and
// This Builder is needed to provide a BuildContext that is
// "inside" the NestedScrollView, so that
// sliverOverlapAbsorberHandleFor() can find the
// NestedScrollView.
The correct way is to get the controller used by CustomScrollView, not to add a new one to it.
It can be done by adding a Builder
above the CustomScrollView) and assign the controller to _scrollController.
...
body: NestedScrollView(
...
body: Builder(
builder: (context){
_scrollController = PrimaryScrollController.of(context);
return CustomScrollView(
...
},
),
),
...
RaSha
I'm a software engineer and mobile developer trying to learn more...
Updated on December 26, 2022Comments
-
RaSha over 1 year
I'm trying to auto scroll to the end of a
SliverList
that is inside aCustomScrollView
.SliverList
itself doesn't have a controller property so I have to pass aScrollController
to theCustomScrollView
.The problem is when I pass a controller to the
CustomScrollView
its behavior changes and it's no longer scrolls the outer list and would not cause a collapsedSliverAppBar
widget. How can I auto scrollSliverList
and also keep the behavior ofCustomScrollView
as before?Here is my code:
class _MyHomePageState extends State<MyHomePage> { ScrollController _scrollController = ScrollController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), floatingActionButton: FloatingActionButton( onPressed: () { _scrollController.animateTo( _scrollController.position.maxScrollExtent, curve: Curves.easeOut, duration: const Duration(seconds: 1), ); }, ), body: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return <Widget>[ SliverAppBar( expandedHeight: 230.0, pinned: true, flexibleSpace: FlexibleSpaceBar( title: Text('SliverAppBar Expand'), ), ) ]; }, body: CustomScrollView( //When controller is passed to CustomScrollView, its behavior changes // controller: _scrollController, slivers: [ //Some widgets are here SliverList( delegate: SliverChildBuilderDelegate( (context, index) { return Container( height: 80, color: Colors.primaries[index % Colors.primaries.length], alignment: Alignment.center, child: Text( 'Item : $index', ), ); }, childCount: 20, ), ), ], ), ) , ); } }
-
RaSha over 3 yearsThank you for such a detailed answer!