demo_launcher/lib/main.dart does not have bottom-overscroll

Rather than trying to clamp the scroll offset during scrolling, we detect when
we might have exceeded our maxScrollOffset and settle the scroll offset back in
bounds.

Fixes #287

R=eseidel@chromium.org, eseidel@google.com

Review URL: https://codereview.chromium.org/1226373003 .
This commit is contained in:
Adam Barth 2015-07-09 13:43:30 -07:00
parent 61c2a1695b
commit fdb030a242
3 changed files with 27 additions and 21 deletions

View File

@ -58,17 +58,17 @@ class OverscrollBehavior extends ScrollBehavior {
: _contentsHeight = contentsHeight,
_containerHeight = containerHeight;
double get maxScroll => math.max(0.0, _contentsHeight - _containerHeight);
double get maxScrollOffset => math.max(0.0, _contentsHeight - _containerHeight);
Simulation release(Particle particle) {
System system;
if ((particle.position >= 0.0) && (particle.position < maxScroll)) {
if ((particle.position >= 0.0) && (particle.position < maxScrollOffset)) {
if (particle.velocity == 0.0)
return null;
System slowdownSystem = new ParticleInBoxWithFriction(
particle: particle,
friction: _kScrollFriction,
box: new GeofenceBox(min: 0.0, max: maxScroll, onEscape: () {
box: new GeofenceBox(min: 0.0, max: maxScrollOffset, onEscape: () {
(system as Multisystem).transitionToSystem(new ParticleInBoxWithFriction(
particle: particle,
friction: _kOverscrollFriction,
@ -92,9 +92,9 @@ class OverscrollBehavior extends ScrollBehavior {
targetPosition: 0.0);
return new ParticleClimbingRamp(
particle: particle,
box: new ClosedBox(min: maxScroll),
box: new ClosedBox(min: maxScrollOffset),
theta: _kBounceSlopeAngle,
targetPosition: maxScroll);
targetPosition: maxScrollOffset);
}
double applyCurve(double scrollOffset, double scrollDelta) {
@ -107,8 +107,8 @@ class OverscrollBehavior extends ScrollBehavior {
// do similar things for overscroll in the other direction.
if (newScrollOffset < 0.0) {
newScrollOffset -= (newScrollOffset - math.min(0.0, scrollOffset)) / 2.0;
} else if (newScrollOffset > maxScroll) {
newScrollOffset -= (newScrollOffset - math.max(maxScroll, scrollOffset)) / 2.0;
} else if (newScrollOffset > maxScrollOffset) {
newScrollOffset -= (newScrollOffset - math.max(maxScrollOffset, scrollOffset)) / 2.0;
}
return newScrollOffset;
}

View File

@ -23,6 +23,7 @@ abstract class FixedHeightScrollable extends Scrollable {
/// Subclasses must implement `get itemCount` to tell FixedHeightScrollable
/// how many items there are in the list.
int get itemCount;
int _previousItemCount;
void syncFields(FixedHeightScrollable source) {
padding = source.padding;
@ -41,14 +42,6 @@ abstract class FixedHeightScrollable extends Scrollable {
});
}
bool scrollTo(double newScrollOffset) {
if (_height != null && _height > 0.0) {
double maxScrollOffset = math.max(0.0, itemCount * itemHeight - _height);
newScrollOffset = math.min(newScrollOffset, maxScrollOffset);
}
return super.scrollTo(newScrollOffset);
}
void _updateContentsHeight() {
double contentsHeight = itemHeight * itemCount;
if (padding != null)
@ -56,8 +49,17 @@ abstract class FixedHeightScrollable extends Scrollable {
scrollBehavior.contentsHeight = contentsHeight;
}
void _updateScrollOffset() {
if (scrollOffset > scrollBehavior.maxScrollOffset)
settleScrollOffset();
}
Widget buildContent() {
_updateContentsHeight();
if (itemCount != _previousItemCount) {
_previousItemCount = itemCount;
_updateContentsHeight();
_updateScrollOffset();
}
var itemShowIndex = 0;
var itemShowCount = 0;

View File

@ -27,9 +27,9 @@ enum ScrollDirection { vertical, horizontal }
abstract class Scrollable extends StatefulComponent {
Scrollable({
String key,
this.backgroundColor,
this.direction: ScrollDirection.vertical
String key,
this.backgroundColor,
this.direction: ScrollDirection.vertical
}) : super(key: key);
Color backgroundColor;
@ -122,6 +122,10 @@ abstract class Scrollable extends StatefulComponent {
super.didUnmount();
}
void settleScrollOffset() {
_startSimulation(_createParticle());
}
void _stopSimulation() {
if (_simulation == null)
return;
@ -147,7 +151,7 @@ abstract class Scrollable extends StatefulComponent {
void _handlePointerUpOrCancel(_) {
if (_simulation == null)
_startSimulation(_createParticle());
settleScrollOffset();
}
void _handleScrollUpdate(sky.GestureEvent event) {
@ -162,7 +166,7 @@ abstract class Scrollable extends StatefulComponent {
}
void _handleFlingCancel(sky.GestureEvent event) {
_startSimulation(_createParticle());
settleScrollOffset();
}
void _handleWheel(sky.WheelEvent event) {