Simplify integration with Scrollable (#4394)
This patch exposes a convenience function on Scrollable that helps with updating the scroll extents and ports several clients over to using it.
This commit is contained in:
parent
b96d1dfc24
commit
48ed80b3be
@ -197,27 +197,19 @@ class LazyBlock extends StatelessWidget {
|
|||||||
/// See [LazyBlockDelegate] for details.
|
/// See [LazyBlockDelegate] for details.
|
||||||
final LazyBlockDelegate delegate;
|
final LazyBlockDelegate delegate;
|
||||||
|
|
||||||
void _handleExtentsChanged(
|
|
||||||
ScrollableState state,
|
|
||||||
double contentExtent,
|
|
||||||
double containerExtent,
|
|
||||||
double minScrollOffset) {
|
|
||||||
final BoundedBehavior scrollBehavior = state.scrollBehavior;
|
|
||||||
state.didUpdateScrollBehavior(scrollBehavior.updateExtents(
|
|
||||||
contentExtent: contentExtent,
|
|
||||||
containerExtent: containerExtent,
|
|
||||||
minScrollOffset: minScrollOffset,
|
|
||||||
scrollOffset: state.scrollOffset
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
||||||
return new LazyBlockViewport(
|
return new LazyBlockViewport(
|
||||||
startOffset: scrollOffset,
|
startOffset: scrollOffset,
|
||||||
mainAxis: scrollDirection,
|
mainAxis: scrollDirection,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
onExtentsChanged: (double contentExtent, double containerExtent, double minScrollOffset) {
|
onExtentsChanged: (double contentExtent, double containerExtent, double minScrollOffset) {
|
||||||
_handleExtentsChanged(state, contentExtent, containerExtent, minScrollOffset);
|
final BoundedBehavior scrollBehavior = state.scrollBehavior;
|
||||||
|
state.didUpdateScrollBehavior(scrollBehavior.updateExtents(
|
||||||
|
contentExtent: contentExtent,
|
||||||
|
containerExtent: containerExtent,
|
||||||
|
minScrollOffset: minScrollOffset,
|
||||||
|
scrollOffset: state.scrollOffset
|
||||||
|
));
|
||||||
},
|
},
|
||||||
delegate: delegate
|
delegate: delegate
|
||||||
);
|
);
|
||||||
|
@ -418,6 +418,24 @@ class ScrollableState<T extends Scrollable> extends State<T> {
|
|||||||
scrollTo(newScrollOffset);
|
scrollTo(newScrollOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates the scroll behavior for the new content and container extent.
|
||||||
|
///
|
||||||
|
/// For convenience, this function combines three common operations:
|
||||||
|
///
|
||||||
|
/// 1. Updating the scroll behavior extents with
|
||||||
|
/// [ExtentScrollBehavior.updateExtents].
|
||||||
|
/// 2. Notifying this object that the scroll behavior was updated with
|
||||||
|
/// [didUpdateScrollBehavior].
|
||||||
|
/// 3. Updating this object's gesture detector with [updateGestureDetector].
|
||||||
|
void handleExtentsChanged(double contentExtent, double containerExtent) {
|
||||||
|
didUpdateScrollBehavior(scrollBehavior.updateExtents(
|
||||||
|
contentExtent: contentExtent,
|
||||||
|
containerExtent: containerExtent,
|
||||||
|
scrollOffset: scrollOffset
|
||||||
|
));
|
||||||
|
updateGestureDetector();
|
||||||
|
}
|
||||||
|
|
||||||
/// Fling the scroll offset with the given velocity.
|
/// Fling the scroll offset with the given velocity.
|
||||||
///
|
///
|
||||||
/// Calling this function starts a physics-based animation of the scroll
|
/// Calling this function starts a physics-based animation of the scroll
|
||||||
@ -685,7 +703,7 @@ class ScrollNotification extends Notification {
|
|||||||
|
|
||||||
/// A simple scrolling widget that has a single child. Use this widget if
|
/// A simple scrolling widget that has a single child. Use this widget if
|
||||||
/// you are not worried about offscreen widgets consuming resources.
|
/// you are not worried about offscreen widgets consuming resources.
|
||||||
class ScrollableViewport extends StatefulWidget {
|
class ScrollableViewport extends StatelessWidget {
|
||||||
ScrollableViewport({
|
ScrollableViewport({
|
||||||
Key key,
|
Key key,
|
||||||
this.initialScrollOffset,
|
this.initialScrollOffset,
|
||||||
@ -761,39 +779,18 @@ class ScrollableViewport extends StatefulWidget {
|
|||||||
/// The widget that will be scrolled. It will become the child of a Scrollable.
|
/// The widget that will be scrolled. It will become the child of a Scrollable.
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
@override
|
|
||||||
_ScrollableViewportState createState() => new _ScrollableViewportState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ScrollableViewportState extends State<ScrollableViewport> {
|
|
||||||
double _viewportSize = 0.0;
|
|
||||||
double _childSize = 0.0;
|
|
||||||
|
|
||||||
Offset _handlePaintOffsetUpdateNeeded(ScrollableState state, ViewportDimensions dimensions) {
|
|
||||||
// We make various state changes here but don't have to do so in a
|
|
||||||
// setState() callback because we are called during layout and all
|
|
||||||
// we're updating is the new offset, which we are providing to the
|
|
||||||
// render object via our return value.
|
|
||||||
_viewportSize = config.scrollDirection == Axis.vertical ? dimensions.containerSize.height : dimensions.containerSize.width;
|
|
||||||
_childSize = config.scrollDirection == Axis.vertical ? dimensions.contentSize.height : dimensions.contentSize.width;
|
|
||||||
state.didUpdateScrollBehavior(state.scrollBehavior.updateExtents(
|
|
||||||
contentExtent: _childSize,
|
|
||||||
containerExtent: _viewportSize,
|
|
||||||
scrollOffset: state.scrollOffset
|
|
||||||
));
|
|
||||||
state.updateGestureDetector();
|
|
||||||
return state.scrollOffsetToPixelDelta(state.scrollOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
||||||
return new Viewport(
|
return new Viewport(
|
||||||
paintOffset: state.scrollOffsetToPixelDelta(scrollOffset),
|
paintOffset: state.scrollOffsetToPixelDelta(scrollOffset),
|
||||||
mainAxis: config.scrollDirection,
|
mainAxis: scrollDirection,
|
||||||
anchor: config.scrollAnchor,
|
anchor: scrollAnchor,
|
||||||
onPaintOffsetUpdateNeeded: (ViewportDimensions dimensions) {
|
onPaintOffsetUpdateNeeded: (ViewportDimensions dimensions) {
|
||||||
return _handlePaintOffsetUpdateNeeded(state, dimensions);
|
final double contentExtent = scrollDirection == Axis.vertical ? dimensions.contentSize.height : dimensions.contentSize.width;
|
||||||
|
final double containerExtent = scrollDirection == Axis.vertical ? dimensions.containerSize.height : dimensions.containerSize.width;
|
||||||
|
state.handleExtentsChanged(contentExtent, containerExtent);
|
||||||
|
return state.scrollOffsetToPixelDelta(state.scrollOffset);
|
||||||
},
|
},
|
||||||
child: config.child
|
child: child
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,14 +801,14 @@ class _ScrollableViewportState extends State<ScrollableViewport> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Widget result = new Scrollable(
|
final Widget result = new Scrollable(
|
||||||
key: config.scrollableKey,
|
key: scrollableKey,
|
||||||
initialScrollOffset: config.initialScrollOffset,
|
initialScrollOffset: initialScrollOffset,
|
||||||
scrollDirection: config.scrollDirection,
|
scrollDirection: scrollDirection,
|
||||||
scrollAnchor: config.scrollAnchor,
|
scrollAnchor: scrollAnchor,
|
||||||
onScrollStart: config.onScrollStart,
|
onScrollStart: onScrollStart,
|
||||||
onScroll: config.onScroll,
|
onScroll: onScroll,
|
||||||
onScrollEnd: config.onScrollEnd,
|
onScrollEnd: onScrollEnd,
|
||||||
snapOffsetCallback: config.snapOffsetCallback,
|
snapOffsetCallback: snapOffsetCallback,
|
||||||
builder: _buildContent
|
builder: _buildContent
|
||||||
);
|
);
|
||||||
return ScrollConfiguration.wrap(context, result);
|
return ScrollConfiguration.wrap(context, result);
|
||||||
|
@ -66,21 +66,11 @@ class ScrollableGrid extends StatelessWidget {
|
|||||||
final GridDelegate delegate;
|
final GridDelegate delegate;
|
||||||
final Iterable<Widget> children;
|
final Iterable<Widget> children;
|
||||||
|
|
||||||
void _handleExtentsChanged(ScrollableState state, double contentExtent, double containerExtent) {
|
|
||||||
state.didUpdateScrollBehavior(state.scrollBehavior.updateExtents(
|
|
||||||
contentExtent: contentExtent,
|
|
||||||
containerExtent: containerExtent,
|
|
||||||
scrollOffset: state.scrollOffset
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
||||||
return new GridViewport(
|
return new GridViewport(
|
||||||
startOffset: scrollOffset,
|
startOffset: scrollOffset,
|
||||||
delegate: delegate,
|
delegate: delegate,
|
||||||
onExtentsChanged: (double contentExtent, double containerExtent) {
|
onExtentsChanged: state.handleExtentsChanged,
|
||||||
_handleExtentsChanged(state, contentExtent, containerExtent);
|
|
||||||
},
|
|
||||||
children: children
|
children: children
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -101,18 +101,10 @@ class ScrollableList extends StatelessWidget {
|
|||||||
/// The axis along which this widget should scroll.
|
/// The axis along which this widget should scroll.
|
||||||
final Iterable<Widget> children;
|
final Iterable<Widget> children;
|
||||||
|
|
||||||
void _handleExtentsChanged(ScrollableState state, double contentExtent, double containerExtent) {
|
|
||||||
state.didUpdateScrollBehavior(state.scrollBehavior.updateExtents(
|
|
||||||
contentExtent: itemsWrap ? double.INFINITY : contentExtent,
|
|
||||||
containerExtent: containerExtent,
|
|
||||||
scrollOffset: state.scrollOffset
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
||||||
return new ListViewport(
|
return new ListViewport(
|
||||||
onExtentsChanged: (double contentExtent, double containerExtent) {
|
onExtentsChanged: (double contentExtent, double containerExtent) {
|
||||||
_handleExtentsChanged(state, contentExtent, containerExtent);
|
state.handleExtentsChanged(itemsWrap ? double.INFINITY : contentExtent, containerExtent);
|
||||||
},
|
},
|
||||||
scrollOffset: scrollOffset,
|
scrollOffset: scrollOffset,
|
||||||
mainAxis: scrollDirection,
|
mainAxis: scrollDirection,
|
||||||
@ -425,19 +417,9 @@ class ScrollableLazyList extends StatelessWidget {
|
|||||||
/// The insets for the entire list.
|
/// The insets for the entire list.
|
||||||
final EdgeInsets padding;
|
final EdgeInsets padding;
|
||||||
|
|
||||||
void _handleExtentsChanged(ScrollableState state, double contentExtent, double containerExtent) {
|
|
||||||
state.didUpdateScrollBehavior(state.scrollBehavior.updateExtents(
|
|
||||||
contentExtent: contentExtent,
|
|
||||||
containerExtent: containerExtent,
|
|
||||||
scrollOffset: state.scrollOffset
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
|
||||||
return new LazyListViewport(
|
return new LazyListViewport(
|
||||||
onExtentsChanged: (double contentExtent, double containerExtent) {
|
onExtentsChanged: state.handleExtentsChanged,
|
||||||
_handleExtentsChanged(state, contentExtent, containerExtent);
|
|
||||||
},
|
|
||||||
scrollOffset: scrollOffset,
|
scrollOffset: scrollOffset,
|
||||||
mainAxis: scrollDirection,
|
mainAxis: scrollDirection,
|
||||||
anchor: scrollAnchor,
|
anchor: scrollAnchor,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user