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
jumpToIndexandanimateToIndexto scroll to the specificindex - No breaking for your current sliver widgets, e.g.,
ListView/GridView,SliverList/SliverGrid/SliverAppBar - support almost official
RenderSliverthat 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
ScrollObserverwith 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
ScrollObserverto 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 ScrollObserverwould observe all children for slivers, e.g.,SliverList/SliverGrid, so all items should have the sameScrollObserverinstead of creating a differentScrollObserverfor each item.
Observing a single sliver #
-
if you want to use
ScrollControllerdirectly, you could create a standaloneScrollObserverby using:ScrollObserver.singleChildfor a sliver with a single child, such asSliverAppBarScrollObserver.multiChildfor a sliver with multi children, such asSliverList/SliverGrid
-
if you prefer using
PositionedScrollControllerthat would manageScrollObservercreated by you, you could create a controller byPositionedScrollController.singleObserver. Then, you could create a standaloneScrollObserverby using:PositionedScrollController.createOrObtainObserver:hasMultiChildindicates 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 multipleScrollObservers manually and bind them to different slivers. Each sliver should have an uniqueScrollObserverthat must adopt its type: single child or multi children -
if using
PositionedScrollController, you could createPositionedScrollController.multiObserverto manage multipleScrollObservers automatically. Then, usingPositionedScrollController.createOrObtainObserverto create a correspondingScrollObserverfor each sliver.
PositionedScrollController #
It has all methods of ScrollController by extends ScrollController and then help you to manage ScrollObserver.
-
PositionedScrollController.singleObservermanage only a singleScrollObserverthat may have single child or multi children -
PositionedScrollController.multiObservermanage multipleScrollObserverthat may have single child or multi children -
createOrObtainObserverparameter required default description hasMultiChild YES true determine if the ScrollObserveris 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 ancestorRenderSliverandParentData. Default to50internally, 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 ofScrollObservernot only when creating it. Setting it only when you ensure you need it.renderToTargetIndex NO null same as targetToRenderIndexbut in converting reversely. -
jumpToIndexandanimateToIndex. (should passdurationandCurveif usinganimateToIndex)parameter required default description index YES N/A the item's index for a sliver. No effects if ScrollObserver.hasMultiChildisfalsewhichObserver NO null the specific ScrollObserverthat is observing a sliver. It is required ifScrollObserver.hasMultiChildistruecloseToEdge YES truetry to scroll indexat the leading edge if not over scrolling; otherwise, only ensure theindexis visible on the screen.
ScrollObserver #
-
ScrollObserver.multiChild: create aScrollObserverthat observes aRenderSliverwith multi children -
ScrollObserver.singleChild: create aScrollObserverthat observes aRenderSliverwith a single child -
jumpToIndexandanimateToIndex. (should passdurationandCurveif usinganimateToIndex)parameter required default description index YES N/A the item's index for a sliver. No effects if ScrollObserver.hasMultiChildisfalsecloseToEdge YES truetry to scroll indexat the leading edge if not over scrolling; otherwise, only ensure theindexis visible on the screen.position YES N/A the ScrollPositionattached to aScrollController