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 {
double _childSize = 0.0;
void _handleViewportSizeChanged(Size newSize) {
_viewportSize = scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width;
_updateScrollBehaviour();
setState(() {
_updateScrollBehaviour();
});
}
void _handleChildSizeChanged(Size newSize) {
_childSize = scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width;
_updateScrollBehaviour();
setState(() {
_updateScrollBehaviour();
});
}
void _updateScrollBehaviour() {
// if you don't call this from build() or syncConstructorArguments(), you must call it from setState().
scrollTo(scrollBehavior.updateExtents(
contentExtent: _childSize,
containerExtent: _viewportSize,
scrollOffset: scrollOffset));
scrollOffset: scrollOffset
));
}
Widget buildContent() {
......@@ -423,6 +429,7 @@ abstract class ScrollableWidgetList extends Scrollable {
}
void _updateScrollBehavior() {
// if you don't call this from build() or syncConstructorArguments(), you must call it from setState().
double contentExtent = itemExtent * itemCount;
if (padding != null)
contentExtent += _leadingPadding + _trailingPadding;
......@@ -636,16 +643,22 @@ class ScrollableMixedWidgetList extends Scrollable {
OverscrollBehavior get scrollBehavior => super.scrollBehavior;
void _handleSizeChanged(Size newSize) {
scrollBy(scrollBehavior.updateExtents(
containerExtent: newSize.height,
scrollOffset: scrollOffset
));
setState(() {
scrollBy(scrollBehavior.updateExtents(
containerExtent: newSize.height,
scrollOffset: scrollOffset
));
});
}
void _handleLayoutChanged() {
double newScrollOffset = scrollBehavior.updateExtents(
contentExtent: layoutState.didReachLastChild ? layoutState.contentsSize : double.INFINITY,
scrollOffset: scrollOffset);
double newScrollOffset;
setState(() {
newScrollOffset = scrollBehavior.updateExtents(
contentExtent: layoutState.didReachLastChild ? layoutState.contentsSize : double.INFINITY,
scrollOffset: scrollOffset
);
});
if (_contentChanged) {
_contentChanged = false;
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