From b84a4251b99c5a46d109c2c3e3719922fc06033c Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Mon, 10 Jun 2024 10:10:40 +0200 Subject: [PATCH] feat: returning null for item getter during animateToItem will stop the animation (#63) --- lib/src/animate_to_item.dart | 21 ++++++++++++++++++--- lib/src/super_sliver_list.dart | 5 +++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/src/animate_to_item.dart b/lib/src/animate_to_item.dart index 0a97759..2c9bcb5 100644 --- a/lib/src/animate_to_item.dart +++ b/lib/src/animate_to_item.dart @@ -16,7 +16,7 @@ class AnimateToItem { }); final ExtentManager extentManager; - final ValueGetter index; + final ValueGetter index; final double alignment; final Rect? rect; final ScrollPosition position; @@ -26,9 +26,13 @@ class AnimateToItem { double lastPosition = 0.0; void animate() { + final index = this.index(); + if (index == null) { + return; + } final start = position.pixels; final estimatedTarget = extentManager.getOffsetToReveal( - index(), + index, alignment, rect: rect, estimationOnly: true, @@ -38,14 +42,25 @@ class AnimateToItem { vsync: position.context.vsync, duration: duration(estimatedDistance), ); + controller.addStatusListener((status) { + if (status == AnimationStatus.completed) { + controller.dispose(); + } + }); final animation = CurvedAnimation( parent: controller, curve: curve(estimatedDistance), ); animation.addListener(() { final value = animation.value; + final index = this.index(); + if (index == null) { + controller.stop(); + controller.dispose(); + return; + } var targetPosition = extentManager.getOffsetToReveal( - index(), + index, alignment, rect: rect, estimationOnly: value < 1.0, diff --git a/lib/src/super_sliver_list.dart b/lib/src/super_sliver_list.dart index 967bdf5..84f9378 100644 --- a/lib/src/super_sliver_list.dart +++ b/lib/src/super_sliver_list.dart @@ -112,7 +112,8 @@ class ListController extends ChangeNotifier { /// /// The index getter will be called repeatedly on every animation tick, which /// allows for accommodating index changes when items are inserted or removed - /// during the animation. + /// during the animation. Returning `null` from the index getter will stop + /// the animation. /// /// The optional [rect] parameter describes which area of that target item /// should be revealed in the viewport. If omitted, the entire item @@ -124,7 +125,7 @@ class ListController extends ChangeNotifier { /// the middle of the viewport. If the value is 1.0, the item will be /// positioned at the trailing edge of the viewport. void animateToItem({ - required ValueGetter index, + required ValueGetter index, required ScrollController scrollController, required double alignment, required Duration Function(double estimatedDistance) duration,