positioned_scroll_observer 1.0.0
positioned_scroll_observer: ^1.0.0 copied to clipboard
An elegant scroll observer that support all official slivers. You could use this package to jump/animateToIndex for your SliverList/Grid without breaking your current widgets. Just wrap your item widg [...]
Features #
- using
jumpToIndex
andanimateToIndex
to scroll to the specificindex
- No breaking for your current sliver widgets, e.g.,
ListView
/GridView
,SliverList
/SliverGrid
/SliverAppBar
- support almost official
RenderSliver
that has single child or multi children





Getting started #
Use ScrollController
#
- create a
ScrollObserver
final ScrollController _controller = ScrollController();
late final ScrollObserver _observer =
ScrollObserver.multiChild(itemCount: _itemCount);
- bind
ScrollObserver
with the item widget/builder that must be wrapped byObserverProxy
ListView.builder(
controller: _controller,
itemBuilder: (context, index) => ObserverProxy(
observer: _observer,
child: ListTile(
key: ValueKey<int>(index),
leading: const CircleAvatar(
child: Text("L"),
),
title: Text("Positioned List Example $index"),
),
),
itemCount: _itemCount,
);
- use
jumpToIndex
/animateToIndex
_observer.jumpToIndex(
index,
position: _controller.position,
);
_observer.animateToIndex(
index,
position: _controller.position,
duration: const Duration(milliseconds: 200),
curve: Curves.fastLinearToSlowEaseIn,
);
There you go
Use PositionedScrollController
for ListView
that only has a single RenderSliver
#
- create
PositionedScrollController
final PositionedScrollController _controller =
PositionedScrollController.singleObserver();
- bind
ScrollObserver
to item widget/builder
ListView.builder(
controller: _controller,
itemBuilder: (context, index) => ObserverProxy(
observer: _controller.createOrObtainObserver(
itemCount: _itemCount,
),
child: ListTile(
key: ValueKey<int>(index),
leading: const CircleAvatar(
child: Text("L"),
),
title: Text("Positioned List Example $index"),
),
),
itemCount: _itemCount,
);
- use
jumpToIndex
/animateToIndex
_controller.jumpToIndex(index);
_controller.animateToIndex(
index,
duration: const Duration(milliseconds: 200),
curve: Curves.fastLinearToSlowEaseIn,
);
There you go
Usage #
- The item widget/builder must be wrapped using
ObserverProxy
ScrollObserver
would observe all children for slivers, e.g.,SliverList
/SliverGrid
, so all items should have the sameScrollObserver
instead of creating a differentScrollObserver
for each item.
Observing a single sliver #
-
if you want to use
ScrollController
directly, you could create a standaloneScrollObserver
by using:ScrollObserver.singleChild
for a sliver with a single child, such asSliverAppBar
ScrollObserver.multiChild
for a sliver with multi children, such asSliverList
/SliverGrid
-
if you prefer using
PositionedScrollController
that would manageScrollObserver
created by you, you could create a controller byPositionedScrollController.singleObserver
. Then, you could create a standaloneScrollObserver
by using:PositionedScrollController.createOrObtainObserver
:hasMultiChild
indicates if this observer is for a sliver with multi children
Observing multiple slivers (typically for CustomScrollView
that has multiple slivers) #
-
if using
ScrollController
, you have to create multipleScrollObserver
s manually and bind them to different slivers. Each sliver should have an uniqueScrollObserver
that must adopt its type: single child or multi children -
if using
PositionedScrollController
, you could createPositionedScrollController.multiObserver
to manage multipleScrollObserver
s automatically. Then, usingPositionedScrollController.createOrObtainObserver
to create a correspondingScrollObserver
for each sliver.
PositionedScrollController
#
It has all methods of ScrollController
by extends ScrollController
and then help you to manage ScrollObserver
.
-
PositionedScrollController.singleObserver
manage only a singleScrollObserver
that may have single child or multi children -
PositionedScrollController.multiObserver
manage multipleScrollObserver
that may have single child or multi children -
createOrObtainObserver
parameter required default description hasMultiChild YES true determine if the ScrollObserver
is for a sliver that has multi childrenitemCount No null the sliver's item count. if null, the observer would behave as a infinite scroll view maxTraceCount NO null the maximum count when tracing ObserverProxy
's ancestorRenderSliver
andParentData
. Default to50
internally, only setting it when you ensure you need to trace more nodes.targetToRenderIndex NO null sometimes, the target index to which users want to scroll may not be same as the current render index. By using [targetToRenderIndex], users could define how to map the target index to a render index, e.g., ListView.separated
/ReorderableListView
. Users could set it on an instance ofScrollObserver
not only when creating it. Setting it only when you ensure you need it.renderToTargetIndex NO null same as targetToRenderIndex
but in converting reversely. -
jumpToIndex
andanimateToIndex
. (should passduration
andCurve
if usinganimateToIndex
)parameter required default description index YES N/A the item's index for a sliver. No effects if ScrollObserver.hasMultiChild
isfalse
whichObserver NO null the specific ScrollObserver
that is observing a sliver. It is required ifScrollObserver.hasMultiChild
istrue
closeToEdge YES true
try to scroll index
at the leading edge if not over scrolling; otherwise, only ensure theindex
is visible on the screen.
ScrollObserver
#
-
ScrollObserver.multiChild
: create aScrollObserver
that observes aRenderSliver
with multi children -
ScrollObserver.singleChild
: create aScrollObserver
that observes aRenderSliver
with a single child -
jumpToIndex
andanimateToIndex
. (should passduration
andCurve
if usinganimateToIndex
)parameter required default description index YES N/A the item's index for a sliver. No effects if ScrollObserver.hasMultiChild
isfalse
closeToEdge YES true
try to scroll index
at the leading edge if not over scrolling; otherwise, only ensure theindex
is visible on the screen.position YES N/A the ScrollPosition
attached to aScrollController