From 5a21cb9908aed8b512ef4fcacd199c2a0d0dab29 Mon Sep 17 00:00:00 2001 From: yakagami <92773903+yakagami@users.noreply.github.com> Date: Sun, 23 Jun 2024 13:57:09 -0700 Subject: [PATCH] expose ScrollPosition as unstableScrollPosition in ScrollOffsetController --- .../lib/src/scrollable_positioned_list.dart | 9 +++++++ .../test/scroll_offset_controller_test.dart | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/packages/scrollable_positioned_list/lib/src/scrollable_positioned_list.dart b/packages/scrollable_positioned_list/lib/src/scrollable_positioned_list.dart index 60045e9b..70e731b0 100644 --- a/packages/scrollable_positioned_list/lib/src/scrollable_positioned_list.dart +++ b/packages/scrollable_positioned_list/lib/src/scrollable_positioned_list.dart @@ -279,6 +279,15 @@ class ItemScrollController { /// This is an experimental API and is subject to change. /// Behavior may be ill-defined in some cases. Please file bugs. class ScrollOffsetController { + /// ScrollPosition of the current ScrollablePositionedList. Values such as + /// pixels, maxScrollExtent and jumpTo are not necessarily defined to start + /// from the beginning of the list. When itemScrollController.jumpTo is + /// called, the list will begin from that index. unstableScrollPosition.jumpTo + /// will cause the application to freeze at very large values as it must build + /// all the widgets between the starting offset and the ending offset. + ScrollPosition get unstableScrollPosition => + _scrollableListState!.primary.scrollController.position; + Future animateScroll( {required double offset, required Duration duration, diff --git a/packages/scrollable_positioned_list/test/scroll_offset_controller_test.dart b/packages/scrollable_positioned_list/test/scroll_offset_controller_test.dart index 31ffc7f3..54d241ac 100644 --- a/packages/scrollable_positioned_list/test/scroll_offset_controller_test.dart +++ b/packages/scrollable_positioned_list/test/scroll_offset_controller_test.dart @@ -225,4 +225,30 @@ void main() { await tester.pumpAndSettle(); }); + + testWidgets('Programtically jump down 50 pixels', + (WidgetTester tester) async { + final scrollDistance = 50.0; + + ScrollOffsetController scrollOffsetController = ScrollOffsetController(); + + await setUpWidgetTest( + tester, + scrollOffsetController: scrollOffsetController, + initialIndex: 5, + ); + + final originalOffset = tester.getTopLeft(find.text('Item 5')).dy; + + final currentPosition = + scrollOffsetController.unstableScrollPosition.pixels; + final newPosition = currentPosition - scrollDistance; + + scrollOffsetController.unstableScrollPosition.jumpTo(newPosition); + await tester.pumpAndSettle(); + + final newOffset = tester.getTopLeft(find.text('Item 5')).dy; + + expect(newOffset - originalOffset, scrollDistance); + }); }