Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend ScrollOffsetController to current position and scroll without animation #487

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,21 @@ 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 {
Future<void> animateScroll(
{required double offset,
required Duration duration,
Curve curve = Curves.linear}) async {
final currentPosition =
_scrollableListState!.primary.scrollController.offset;
_ScrollablePositionedListState? _scrollableListState;

void _attach(_ScrollablePositionedListState scrollableListState) {
assert(_scrollableListState == null);
_scrollableListState = scrollableListState;
}

double get currentPosition =>
_scrollableListState!.primary.scrollController.offset;

Future<void> animateScroll({
required double offset,
required Duration duration,
Curve curve = Curves.linear,
}) async {
final newPosition = currentPosition + offset;
await _scrollableListState!.primary.scrollController.animateTo(
newPosition,
Expand All @@ -293,11 +302,13 @@ class ScrollOffsetController {
);
}

_ScrollablePositionedListState? _scrollableListState;

void _attach(_ScrollablePositionedListState scrollableListState) {
assert(_scrollableListState == null);
_scrollableListState = scrollableListState;
void moveScroll({
required double offset,
}) {
final newPosition = currentPosition + offset;
_scrollableListState!.primary.scrollController.jumpTo(
newPosition,
);
}

void _detach() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void main() {
);
}

testWidgets('Programtically scroll down 50 pixels',
testWidgets('Programmatically scroll down 50 pixels',
(WidgetTester tester) async {
final scrollDistance = 50.0;

Expand All @@ -84,7 +84,7 @@ void main() {
initialIndex: 5,
);

final originalOffest = tester.getTopLeft(find.text('Item 5')).dy;
final originalOffset = tester.getTopLeft(find.text('Item 5')).dy;

unawaited(scrollOffsetController.animateScroll(
offset: -scrollDistance,
Expand All @@ -94,10 +94,10 @@ void main() {

final newOffset = tester.getTopLeft(find.text('Item 5')).dy;

expect(newOffset - originalOffest, scrollDistance);
expect(newOffset - originalOffset, scrollDistance);
});

testWidgets('Programtically scroll left 50 pixels',
testWidgets('Programmatically scroll left 50 pixels',
(WidgetTester tester) async {
final scrollDistance = 50.0;

Expand All @@ -110,7 +110,7 @@ void main() {
scrollDirection: Axis.horizontal,
);

final originalOffest = tester.getTopLeft(find.text('Item 5')).dx;
final originalOffset = tester.getTopLeft(find.text('Item 5')).dx;

unawaited(scrollOffsetController.animateScroll(
offset: -scrollDistance,
Expand All @@ -120,10 +120,10 @@ void main() {

final newOffset = tester.getTopLeft(find.text('Item 5')).dx;

expect(newOffset - originalOffest, scrollDistance);
expect(newOffset - originalOffset, scrollDistance);
});

testWidgets('Programtically scroll down 50 pixels, stop half way',
testWidgets('Programmatically scroll down 50 pixels, stop half way',
(WidgetTester tester) async {
final scrollDistance = 50.0;

Expand All @@ -135,7 +135,7 @@ void main() {
initialIndex: 5,
);

final originalOffest = tester.getTopLeft(find.text('Item 5')).dy;
final originalOffset = tester.getTopLeft(find.text('Item 5')).dy;

unawaited(scrollOffsetController.animateScroll(
offset: -scrollDistance,
Expand All @@ -150,13 +150,13 @@ void main() {

final newOffset = tester.getTopLeft(find.text('Item 5')).dy;

expect(newOffset - originalOffest, scrollDistance ~/ 2);
expect(newOffset - originalOffset, scrollDistance ~/ 2);

await tester.pumpAndSettle();
});

testWidgets(
'Programtically scroll down 50 pixels, stop half way and go back 12',
'Programmatically scroll down 50 pixels, stop half way and go back 12',
(WidgetTester tester) async {
final scrollDistance = 50.0;
final scrollBack = 12.0;
Expand All @@ -169,7 +169,7 @@ void main() {
initialIndex: 5,
);

final originalOffest = tester.getTopLeft(find.text('Item 5')).dy;
final originalOffset = tester.getTopLeft(find.text('Item 5')).dy;

unawaited(scrollOffsetController.animateScroll(
offset: -scrollDistance,
Expand All @@ -187,13 +187,13 @@ void main() {

final newOffset = tester.getTopLeft(find.text('Item 5')).dy;

expect(newOffset - originalOffest, (scrollDistance ~/ 2) - scrollBack);
expect(newOffset - originalOffset, (scrollDistance ~/ 2) - scrollBack);

await tester.pumpAndSettle();
});

testWidgets(
'Programtically scroll down 50 pixels, stop half way and then programtically scroll to iten 100',
'Programmatically scroll down 50 pixels, stop half way and then programmatically scroll to item 100',
(WidgetTester tester) async {
final scrollDistance = 50.0;

Expand Down Expand Up @@ -225,4 +225,49 @@ void main() {

await tester.pumpAndSettle();
});

testWidgets('Programmatically move 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;

scrollOffsetController.moveScroll(
offset: -scrollDistance,
);
await tester.pumpAndSettle();

final newOffset = tester.getTopLeft(find.text('Item 5')).dy;

expect(newOffset - originalOffset, scrollDistance);
});

testWidgets('Fetch scroll position', (WidgetTester tester) async {
final scrollDistance = 100.0;

ScrollOffsetController scrollOffsetController = ScrollOffsetController();

await setUpWidgetTest(
tester,
scrollOffsetController: scrollOffsetController,
initialIndex: 5,
);

expect(scrollOffsetController.currentPosition, isZero);

scrollOffsetController.moveScroll(
offset: scrollDistance,
);
await tester.pumpAndSettle();

expect(scrollOffsetController.currentPosition, equals(scrollDistance));
});
}