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); + }); }