Commit 59f7e7f0 authored by Hixie's avatar Hixie

Fix scrolling of Block.

Since our build function depends on scrollBehavior.isScrollable, any
time we update scrollBehavior we are implicitly updating our state. As
such, we must do so during a setState() call, or else we won't rebuild
and might not bother to listen to the scroll gestures.

This probably broke when we made Block not listen to gestures if it
wasn't overflowing.
parent 244fdab0
...@@ -277,17 +277,23 @@ class ScrollableViewport extends Scrollable { ...@@ -277,17 +277,23 @@ class ScrollableViewport extends Scrollable {
double _childSize = 0.0; double _childSize = 0.0;
void _handleViewportSizeChanged(Size newSize) { void _handleViewportSizeChanged(Size newSize) {
_viewportSize = scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width; _viewportSize = scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width;
setState(() {
_updateScrollBehaviour(); _updateScrollBehaviour();
});
} }
void _handleChildSizeChanged(Size newSize) { void _handleChildSizeChanged(Size newSize) {
_childSize = scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width; _childSize = scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width;
setState(() {
_updateScrollBehaviour(); _updateScrollBehaviour();
});
} }
void _updateScrollBehaviour() { void _updateScrollBehaviour() {
// if you don't call this from build() or syncConstructorArguments(), you must call it from setState().
scrollTo(scrollBehavior.updateExtents( scrollTo(scrollBehavior.updateExtents(
contentExtent: _childSize, contentExtent: _childSize,
containerExtent: _viewportSize, containerExtent: _viewportSize,
scrollOffset: scrollOffset)); scrollOffset: scrollOffset
));
} }
Widget buildContent() { Widget buildContent() {
...@@ -423,6 +429,7 @@ abstract class ScrollableWidgetList extends Scrollable { ...@@ -423,6 +429,7 @@ abstract class ScrollableWidgetList extends Scrollable {
} }
void _updateScrollBehavior() { void _updateScrollBehavior() {
// if you don't call this from build() or syncConstructorArguments(), you must call it from setState().
double contentExtent = itemExtent * itemCount; double contentExtent = itemExtent * itemCount;
if (padding != null) if (padding != null)
contentExtent += _leadingPadding + _trailingPadding; contentExtent += _leadingPadding + _trailingPadding;
...@@ -636,16 +643,22 @@ class ScrollableMixedWidgetList extends Scrollable { ...@@ -636,16 +643,22 @@ class ScrollableMixedWidgetList extends Scrollable {
OverscrollBehavior get scrollBehavior => super.scrollBehavior; OverscrollBehavior get scrollBehavior => super.scrollBehavior;
void _handleSizeChanged(Size newSize) { void _handleSizeChanged(Size newSize) {
setState(() {
scrollBy(scrollBehavior.updateExtents( scrollBy(scrollBehavior.updateExtents(
containerExtent: newSize.height, containerExtent: newSize.height,
scrollOffset: scrollOffset scrollOffset: scrollOffset
)); ));
});
} }
void _handleLayoutChanged() { void _handleLayoutChanged() {
double newScrollOffset = scrollBehavior.updateExtents( double newScrollOffset;
setState(() {
newScrollOffset = scrollBehavior.updateExtents(
contentExtent: layoutState.didReachLastChild ? layoutState.contentsSize : double.INFINITY, contentExtent: layoutState.didReachLastChild ? layoutState.contentsSize : double.INFINITY,
scrollOffset: scrollOffset); scrollOffset: scrollOffset
);
});
if (_contentChanged) { if (_contentChanged) {
_contentChanged = false; _contentChanged = false;
scrollTo(newScrollOffset); scrollTo(newScrollOffset);
......
import 'package:quiver/testing/async.dart';
import 'package:sky/widgets.dart';
import 'package:test/test.dart';
import '../engine/mock_events.dart';
import 'widget_tester.dart';
final Key blockKey = new Key('test');
void main() {
test('Cannot scroll a non-overflowing block', () {
WidgetTester tester = new WidgetTester();
tester.pumpFrame(() {
return new Block([
new Container(
height: 200.0, // less than 600, the height of the test area
child: new Text('Hello')
)
],
key: blockKey);
});
tester.pumpFrameWithoutChange(); // for SizeObservers
Point middleOfContainer = tester.getCenter(tester.findText('Hello'));
Point target = tester.getCenter(tester.findWidget((widget) => widget.key == blockKey));
TestPointer pointer = new TestPointer();
tester.dispatchEvent(pointer.down(target), target);
tester.dispatchEvent(pointer.move(target + const Offset(0.0, -10.0)), target);
tester.pumpFrameWithoutChange(1.0);
expect(tester.getCenter(tester.findText('Hello')) == middleOfContainer, isTrue);
tester.dispatchEvent(pointer.up(), target);
});
test('Can scroll an overflowing block', () {
WidgetTester tester = new WidgetTester();
tester.pumpFrame(() {
return new Block([
new Container(
height: 2000.0, // more than 600, the height of the test area
child: new Text('Hello')
)
],
key: blockKey);
});
tester.pumpFrameWithoutChange(); // for SizeObservers
Point middleOfContainer = tester.getCenter(tester.findText('Hello'));
Point target = tester.getCenter(tester.findWidget((widget) => widget.key == blockKey));
TestPointer pointer = new TestPointer();
tester.dispatchEvent(pointer.down(target), target);
tester.dispatchEvent(pointer.move(target + const Offset(0.0, -10.0)), target);
tester.pumpFrameWithoutChange(1.0);
expect(tester.getCenter(tester.findText('Hello')) == middleOfContainer, isFalse);
tester.dispatchEvent(pointer.up(), target);
});
}
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