mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
parent
61c2a1695b
commit
fdb030a242
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user