Skip to content

Add dedicated rubber band spring for overscroll recovery in BouncingScrollPhysics - #182426

Closed
MTtankkeo wants to merge 6 commits into
flutter:masterfrom
MTtankkeo:bouncing
Closed

MTtankkeo wants to merge 6 commits into
flutter:masterfrom
MTtankkeo:bouncing

Conversation

@MTtankkeo

Copy link
Copy Markdown

Fixes #181752
(for detailed analysis, measurements, and discussion, please refer to the original issue.)

This pull request implements a dedicated “rubber band” physics for overscroll snap-back in BouncingScrollPhysics on iOS to better match the native UIScrollView feel.

546867255-4ad56291-9603-40c1-ae5a-3e319017c3c9

Note

This change adjusts spring constants and simulation behavior
to improve iOS scroll fidelity.

Given that this change primarily involves physics parameter tuning,
it may reasonably qualify as test-exempt. However, I am not entirely
certain what level of automated testing would be considered appropriate.

Please let me know if additional tests are expected,
and I am happy to update the PR accordingly.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@flutter-dashboard

Copy link
Copy Markdown

It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Feb 14, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a dedicated "rubber band" spring simulation for overscroll recovery in BouncingScrollPhysics to better match iOS native behavior. A new rubberBandSpring is defined, and createBallisticSimulation is updated to use it when the scroll position is out of range and stationary. The logic is sound and well-documented. I have one suggestion to improve code readability. Additionally, while this change is primarily about physics tuning, which can be difficult to test, consider adding a unit test to verify that BouncingScrollPhysics.rubberBandSpring is correctly used when the scroll position is out of range and stationary. This would help ensure the new logic is covered.

Comment thread packages/flutter/lib/src/widgets/scroll_physics.dart Outdated
Comment thread packages/flutter/lib/src/widgets/scroll_physics.dart
@justinmc
justinmc requested a review from dkwingsmt February 17, 2026 23:10

@dkwingsmt dkwingsmt left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic change overall! Thank you so much for the investigation, and especially for the figure for demonstration.

I have commented a question.

Regarding tests, do you think the following test is possible?

  • Build a scrollable with this physics, overscroll it, release. For every 0.2s elapsed, check the y position of the content.

Comment thread packages/flutter/lib/src/widgets/scroll_physics.dart
@MTtankkeo

Copy link
Copy Markdown
Author

@dkwingsmt I'm surprised that releasing from stationary uses a different spring from otherwise. I'd imagine that the spring might depend on whether it is an overscroll, but not the starting velocity. Can you check and confirm?

Thanks for pointing this out, I had previously verified this behavior directly in a native iOS app.

There is a clear difference between releasing an overscrolled view from rest and releasing it with residual velocity. With velocity, it behaves like an inertial bounce. From rest, it transitions into a simple exponential snap-back.

So the velocity check is used to distinguish between these two physical states, matching the observed iOS behavior.

@MTtankkeo

Copy link
Copy Markdown
Author

Fantastic change overall! Thank you so much for the investigation, and especially for the figure for demonstration.

I have commented a question.

Regarding tests, do you think the following test is possible?

  • Build a scrollable with this physics, overscroll it, release. For every 0.2s elapsed, check the y position of the content.

@dkwingsmt I’ve added a unit test that verifies the spring selection in createBallisticSimulation. Could you please take a look and let me know if you still think a widget-level test is needed?

Comment thread packages/flutter/lib/src/widgets/scroll_physics.dart Outdated
Comment thread packages/flutter/test/widgets/scroll_physics_test.dart Outdated
@dkwingsmt dkwingsmt added the CICD Run CI/CD label Mar 16, 2026

@dkwingsmt dkwingsmt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for the great work!

@dkwingsmt dkwingsmt added CICD Run CI/CD and removed CICD Run CI/CD labels Mar 16, 2026
@dkwingsmt
dkwingsmt requested a review from Piinks March 16, 2026 17:11
@dkwingsmt

Copy link
Copy Markdown
Contributor

Assigning @Piinks as a second reviewer, since she reviewed the PR that improved Android overscroll physics.

@Piinks Piinks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @MTtankkeo thanks for contributing this! It looks like it is causing some failures, can you take a look?

@flutter-dashboard

Copy link
Copy Markdown

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@dkwingsmt

Copy link
Copy Markdown
Contributor

Thanks for your contribution! Since I haven't seen a reply, I'm going to reluctantly close this pull request for now, but if you get time to address the comments, we'd be more than happy to take a look at a new patch. If you do send a new patch, it would be very useful to reference this one in the description in order to help reviewers see the previous context.

(Also, in light of the Material/Cupertino pause, merging PRs will be paused until the completion of decoupling. Although, we can still continue the review process and reland the PR to the new package after decoupling. So feel free to reopen this PR if you happen to have time. Thank you!)

@dkwingsmt dkwingsmt closed this Apr 6, 2026
flutter-zl pushed a commit to flutter-zl/flutter that referenced this pull request Sep 15, 2026
…crollPhysics (flutter#187568)

> [!NOTE] 
> **Relanding** flutter#182426.
>
> Thank you for your review and guidance on the previous PR.
>
> I'm relanding this with the fix for the test failures that caused the
issue before. *(I've updated the regression test to account for the
faster convergence rate of the new physics.)*

Fixes flutter#181752
*(for detailed analysis, measurements, and discussion, please refer to
the original issue.)*

This pull request implements a dedicated “rubber band” physics for
overscroll snap-back in BouncingScrollPhysics on iOS to better match the
native UIScrollView feel.

<img width="1000" alt="546867255-4ad56291-9603-40c1-ae5a-3e319017c3c9"
src="https://github.com/user-attachments/assets/8e72ebff-fb8f-4613-b042-7668db15bcf5"
/>

- - -

> [!NOTE]
> This change adjusts spring constants and simulation behavior
> to improve iOS scroll fidelity.
>
> Given that this change primarily involves physics parameter tuning,
> it may reasonably qualify as test-exempt. However, I am not entirely
> certain what level of automated testing would be considered
appropriate.
>
> Please let me know if additional tests are expected,
> and I am happy to update the PR accordingly.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Tong Mu <[email protected]>
Co-authored-by: Victor Sanni <[email protected]>
Co-authored-by: Elliott Brooks <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal - Missing dedicated "Rubber Band" physics in BouncingScrollPhysics causes low iOS fidelity

4 participants