@@ -197,6 +197,13 @@ class NestedScrollView extends StatefulWidget {
197
197
final ScrollController ? controller;
198
198
199
199
/// {@macro flutter.widgets.scroll_view.scrollDirection}
200
+ ///
201
+ /// This property only applies to the [Axis] of the outer scroll view,
202
+ /// composed of the slivers returned from [headerSliverBuilder] . Since the
203
+ /// inner scroll view is not directly configured by the [NestedScrollView] ,
204
+ /// for the axes to match, configure the scroll view of the [body] the same
205
+ /// way if they are expected to scroll in the same orientation. This allows
206
+ /// for flexible configurations of the NestedScrollView.
200
207
final Axis scrollDirection;
201
208
202
209
/// Whether the scroll view scrolls in the reading direction.
@@ -210,6 +217,13 @@ class NestedScrollView extends StatefulWidget {
210
217
/// scrolls from top to bottom when [reverse] is false and from bottom to top
211
218
/// when [reverse] is true.
212
219
///
220
+ /// This property only applies to the outer scroll view, composed of the
221
+ /// slivers returned from [headerSliverBuilder] . Since the inner scroll view
222
+ /// is not directly configured by the [NestedScrollView] . For both to scroll
223
+ /// in reverse, configure the scroll view of the [body] the same way if they
224
+ /// are expected to match. This allows for flexible configurations of the
225
+ /// NestedScrollView.
226
+ ///
213
227
/// Defaults to false.
214
228
final bool reverse;
215
229
@@ -232,6 +246,22 @@ class NestedScrollView extends StatefulWidget {
232
246
/// [ScrollMetrics.maxScrollExtent] properties passed to that method. If that
233
247
/// invariant is not maintained, the nested scroll view may respond to user
234
248
/// scrolling erratically.
249
+ ///
250
+ /// This property only applies to the outer scroll view, composed of the
251
+ /// slivers returned from [headerSliverBuilder] . Since the inner scroll view
252
+ /// is not directly configured by the [NestedScrollView] . For both to scroll
253
+ /// with the same [ScrollPhysics] , configure the scroll view of the [body]
254
+ /// the same way if they are expected to match, or use a [ScrollBehavior] as
255
+ /// an ancestor so both the inner and outer scroll views inherit the same
256
+ /// [ScrollPhysics] . This allows for flexible configurations of the
257
+ /// NestedScrollView.
258
+ ///
259
+ /// The [ScrollPhysics] also determine whether or not the [NestedScrollView]
260
+ /// can accept input from the user to change the scroll offset. For example,
261
+ /// [NeverScrollableScrollPhysics] typically will not allow the user to drag a
262
+ /// scroll view, but in this case, if one of the two scroll views can be
263
+ /// dragged, then dragging will be allowed. Configuring both scroll views with
264
+ /// [NeverScrollableScrollPhysics] will disallow dragging in this case.
235
265
final ScrollPhysics ? physics;
236
266
237
267
/// A builder for any widgets that are to precede the inner scroll views (as
@@ -845,17 +875,18 @@ class _NestedScrollCoordinator implements ScrollActivityDelegate, ScrollHoldCont
845
875
if (! _outerPosition! .haveDimensions) {
846
876
return ;
847
877
}
848
- double maxInnerExtent = 0.0 ;
878
+ bool innerCanDrag = false ;
849
879
for (final _NestedScrollPosition position in _innerPositions) {
850
880
if (! position.haveDimensions) {
851
881
return ;
852
882
}
853
- maxInnerExtent = math.max (
854
- maxInnerExtent,
855
- position.maxScrollExtent - position.minScrollExtent,
856
- );
883
+ innerCanDrag = innerCanDrag
884
+ // This refers to the physics of the actual inner scroll position, not
885
+ // the whole NestedScrollView, since it is possible to have different
886
+ // ScrollPhysics for the inner and outer positions.
887
+ || position.physics.shouldAcceptUserOffset (position);
857
888
}
858
- _outerPosition! .updateCanDrag (maxInnerExtent );
889
+ _outerPosition! .updateCanDrag (innerCanDrag );
859
890
}
860
891
861
892
Future <void > animateTo (
@@ -1438,9 +1469,16 @@ class _NestedScrollPosition extends ScrollPosition implements ScrollActivityDele
1438
1469
coordinator.updateCanDrag ();
1439
1470
}
1440
1471
1441
- void updateCanDrag (double totalExtent) {
1442
- context.setCanDrag (physics.allowUserScrolling &&
1443
- (totalExtent > (viewportDimension - maxScrollExtent) || minScrollExtent != maxScrollExtent));
1472
+ void updateCanDrag (bool innerCanDrag) {
1473
+ // This is only called for the outer position
1474
+ assert (coordinator._outerPosition == this );
1475
+ context.setCanDrag (
1476
+ // This refers to the physics of the actual outer scroll position, not
1477
+ // the whole NestedScrollView, since it is possible to have different
1478
+ // ScrollPhysics for the inner and outer positions.
1479
+ physics.shouldAcceptUserOffset (this )
1480
+ || innerCanDrag,
1481
+ );
1444
1482
}
1445
1483
1446
1484
@override
@@ -1756,17 +1794,9 @@ class RenderSliverOverlapAbsorber extends RenderSliver with RenderObjectWithChil
1756
1794
}
1757
1795
child! .layout (constraints, parentUsesSize: true );
1758
1796
final SliverGeometry childLayoutGeometry = child! .geometry! ;
1759
- geometry = SliverGeometry (
1797
+ geometry = childLayoutGeometry. copyWith (
1760
1798
scrollExtent: childLayoutGeometry.scrollExtent - childLayoutGeometry.maxScrollObstructionExtent,
1761
- paintExtent: childLayoutGeometry.paintExtent,
1762
- paintOrigin: childLayoutGeometry.paintOrigin,
1763
1799
layoutExtent: math.max (0 , childLayoutGeometry.paintExtent - childLayoutGeometry.maxScrollObstructionExtent),
1764
- maxPaintExtent: childLayoutGeometry.maxPaintExtent,
1765
- maxScrollObstructionExtent: childLayoutGeometry.maxScrollObstructionExtent,
1766
- hitTestExtent: childLayoutGeometry.hitTestExtent,
1767
- visible: childLayoutGeometry.visible,
1768
- hasVisualOverflow: childLayoutGeometry.hasVisualOverflow,
1769
- scrollOffsetCorrection: childLayoutGeometry.scrollOffsetCorrection,
1770
1800
);
1771
1801
handle._setExtents (
1772
1802
childLayoutGeometry.maxScrollObstructionExtent,
0 commit comments