Commit 48ed80b3 authored by Adam Barth's avatar Adam Barth

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.
parent b96d1dfc
......@@ -197,27 +197,19 @@ class LazyBlock extends StatelessWidget {
/// See [LazyBlockDelegate] for details.
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) {
return new LazyBlockViewport(
startOffset: scrollOffset,
mainAxis: scrollDirection,
padding: padding,
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
);
......
......@@ -418,6 +418,24 @@ class ScrollableState<T extends Scrollable> extends State<T> {
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.
///
/// 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
/// you are not worried about offscreen widgets consuming resources.
class ScrollableViewport extends StatefulWidget {
class ScrollableViewport extends StatelessWidget {
ScrollableViewport({
Key key,
this.initialScrollOffset,
......@@ -761,39 +779,18 @@ class ScrollableViewport extends StatefulWidget {
/// The widget that will be scrolled. It will become the child of a Scrollable.
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) {
return new Viewport(
paintOffset: state.scrollOffsetToPixelDelta(scrollOffset),
mainAxis: config.scrollDirection,
anchor: config.scrollAnchor,
mainAxis: scrollDirection,
anchor: scrollAnchor,
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
Widget build(BuildContext context) {
final Widget result = new Scrollable(
key: config.scrollableKey,
initialScrollOffset: config.initialScrollOffset,
scrollDirection: config.scrollDirection,
scrollAnchor: config.scrollAnchor,
onScrollStart: config.onScrollStart,
onScroll: config.onScroll,
onScrollEnd: config.onScrollEnd,
snapOffsetCallback: config.snapOffsetCallback,
key: scrollableKey,
initialScrollOffset: initialScrollOffset,
scrollDirection: scrollDirection,
scrollAnchor: scrollAnchor,
onScrollStart: onScrollStart,
onScroll: onScroll,
onScrollEnd: onScrollEnd,
snapOffsetCallback: snapOffsetCallback,
builder: _buildContent
);
return ScrollConfiguration.wrap(context, result);
......
......@@ -66,21 +66,11 @@ class ScrollableGrid extends StatelessWidget {
final GridDelegate delegate;
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) {
return new GridViewport(
startOffset: scrollOffset,
delegate: delegate,
onExtentsChanged: (double contentExtent, double containerExtent) {
_handleExtentsChanged(state, contentExtent, containerExtent);
},
onExtentsChanged: state.handleExtentsChanged,
children: children
);
}
......
......@@ -101,18 +101,10 @@ class ScrollableList extends StatelessWidget {
/// The axis along which this widget should scroll.
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) {
return new ListViewport(
onExtentsChanged: (double contentExtent, double containerExtent) {
_handleExtentsChanged(state, contentExtent, containerExtent);
state.handleExtentsChanged(itemsWrap ? double.INFINITY : contentExtent, containerExtent);
},
scrollOffset: scrollOffset,
mainAxis: scrollDirection,
......@@ -425,19 +417,9 @@ class ScrollableLazyList extends StatelessWidget {
/// The insets for the entire list.
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) {
return new LazyListViewport(
onExtentsChanged: (double contentExtent, double containerExtent) {
_handleExtentsChanged(state, contentExtent, containerExtent);
},
onExtentsChanged: state.handleExtentsChanged,
scrollOffset: scrollOffset,
mainAxis: scrollDirection,
anchor: scrollAnchor,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment