Skip to content

Proposal: Make ScrollPhysics reactive #80051

Closed

Description

@jamesblasco

Hello there!
Right now a ScrollPhysics is only updated if you change the class type.

bool _shouldUpdatePosition(Scrollable oldWidget) {
ScrollPhysics? newPhysics = widget.physics ?? widget.scrollBehavior?.getScrollPhysics(context);
ScrollPhysics? oldPhysics = oldWidget.physics ?? oldWidget.scrollBehavior?.getScrollPhysics(context);
do {
if (newPhysics?.runtimeType != oldPhysics?.runtimeType)
return true;

I think it would be great to follow some other patterns inside the flutter framework to allow this class to be reactive. This would be to add a new method inside the ScrollPhysics like

bool shouldReload (covariant ScrollPhysics old) => false;

Notice by default would return false, so the behaviour for all the current ScrollPhysics would be the same as now.

Then when the Scrollable widget updates we would add

  if (newPhysics?.runtimeType != oldPhysics?.runtimeType || 
      newPhysics?.shouldUpdate(oldPhysics!))
        return true;

This pattern can be seen in LocalizationsDelegate, SliverPersistentHeaderDelegate, SliverChildDelegate, ScrollBehavior, and many more. (In the search box from the api website write should to see the rest)

Use case

I am building a ScrollPhysics that allows snapping to different positions if the scrollOffset is too close (Similiar to PageScrollPhysics). This would be very useful for SliverAppBars to accomplish this behaviour, where it only snaps to a expanded/collapsed state, but the scroll can not stop in the middle.

RPReplay_Final1617891051.MP4

It works, but right now it is not reactive. People need to do a hot-restart to see the changes made to it.

CustomScrollView(
   physics: SnapScrollView(offset: 64, range: 20),
   slivers: [
      ....
   ]
);

It is important to consider this comment from the Scrollable doc though.

/// The physics can be changed dynamically, but new physics will only take
/// effect if the _class_ of the provided object changes. Merely constructing
/// a new instance with a different configuration is insufficient to cause the
/// physics to be reapplied. (This is because the final object used is
/// generated dynamically, which can be relatively expensive, and it would be
/// inefficient to speculatively create this object each frame to see if the
/// physics should be updated.)
///
/// See also:
///
/// * [AlwaysScrollableScrollPhysics], which can be used to indicate that the
/// scrollable should react to scroll requests (and possible overscroll)
/// even if the scrollable's contents fit without scrolling being necessary.
final ScrollPhysics? physics;

I don't understand why it would be needed to create this object for each frame to see if has changed its configuration. Right now the type runtime is compared only when the widget or its dependencies are updated. So I think it would be the same to also check it through a shouldUpdate method if the configuration has changed.

Notice the ScrollPhysics class is immutable so it should not change its configuration after created. And when it changes didDependenciesUpdate or didWidgetUpdate should be triggered if is used in that scrollable.

cc: @Piinks

Activity

  1. added
    in triagePresently being triaged by the triage team
    f: scrollingViewports, list views, slivers, etc.
    frameworkflutter/packages/flutter repository. See also f: labels.
    c: proposalA detailed proposal for a change to Flutter
    and removed
    in triagePresently being triaged by the triage team
    on Apr 9, 2021
  2. appinteractive commented on Oct 18, 2021

    @appinteractive

    @jamesblasco any progress or workaround on that issue?

  3. jamesblasco commented on Jan 21, 2022

    @jamesblasco
    ContributorAuthor

    As you can see I did not get any response about it 😅

  4. added
    P3Issues that are less important to the Flutter project
    and removed on Jun 28, 2023
  5. added a commit that references this issue on Aug 27, 2026
    3f531e5
  6. github-actions commented on Sep 10, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  7. locked as resolved and limited conversation to collaborators on Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectc: proposalA detailed proposal for a change to Flutterf: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions