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 { ...@@ -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> { ...@@ -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 { ...@@ -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 { ...@@ -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> { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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,
......
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