@@ -145,6 +145,24 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
145145 double get maxScrollExtent => _maxScrollExtent;
146146 double _maxScrollExtent;
147147
148+ /// The additional velocity added for a [forcePixels] change in a single
149+ /// frame.
150+ ///
151+ /// This value is used by [recommendDeferredLoading] in addition to the
152+ /// [activity] 's [ScrollActivity.velocity] to ask the [physics] whether or
153+ /// not to defer loading. It accounts for the fact that a [forcePixels] call
154+ /// may involve a [ScrollActivity] with 0 velocity, but the scrollable is
155+ /// still instantaneously moving from its current position to a potentially
156+ /// very far position, and which is of interest to callers of
157+ /// [recommendDeferredLoading] .
158+ ///
159+ /// For example, if a scrollable is currently at 5000 pixels, and we [jumpTo]
160+ /// 0 to get back to the top of the list, we would have an implied velocity of
161+ /// -5000 and an `activity.velocity` of 0. The jump may be going past a
162+ /// number of resource intensive widgets which should avoid doing work if the
163+ /// position jumps past them.
164+ double _impliedVelocity = 0 ;
165+
148166 @override
149167 double get pixels => _pixels;
150168 double _pixels;
@@ -343,8 +361,13 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
343361 @protected
344362 void forcePixels (double value) {
345363 assert (pixels != null );
364+ assert (value != null );
365+ _impliedVelocity = value - _pixels;
346366 _pixels = value;
347367 notifyListeners ();
368+ SchedulerBinding .instance.addPostFrameCallback ((Duration timeStamp) {
369+ _impliedVelocity = 0 ;
370+ });
348371 }
349372
350373 /// Called whenever scrolling ends, to store the current scroll offset in a
@@ -834,7 +857,12 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
834857 assert (context != null );
835858 assert (activity != null );
836859 assert (activity.velocity != null );
837- return physics.recommendDeferredLoading (activity.velocity, copyWith (), context);
860+ assert (_impliedVelocity != null );
861+ return physics.recommendDeferredLoading (
862+ activity.velocity + _impliedVelocity,
863+ copyWith (),
864+ context,
865+ );
838866 }
839867
840868 @override
0 commit comments