mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Intead of hard-coding the notion of bounded scrolling into Scrollable, this CL factors out a ScrollCurve class that applies the bounds. In the future, we'll refine this mechanism to implement overflow scrolling. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1005633002
78 lines
2.0 KiB
Dart
78 lines
2.0 KiB
Dart
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import '../animation/fling_curve.dart';
|
|
import '../animation/scroll_curve.dart';
|
|
import '../fn.dart';
|
|
import 'dart:sky' as sky;
|
|
|
|
abstract class Scrollable extends Component {
|
|
ScrollCurve scrollCurve;
|
|
double get scrollOffset => _scrollOffset;
|
|
|
|
double _scrollOffset = 0.0;
|
|
FlingCurve _flingCurve;
|
|
int _flingAnimationId;
|
|
|
|
Scrollable({Object key, this.scrollCurve}) : super(key: key) {
|
|
events.listen('gestureflingstart', _handleFlingStart);
|
|
events.listen('gestureflingcancel', _handleFlingCancel);
|
|
events.listen('gesturescrollupdate', _handleScrollUpdate);
|
|
events.listen('wheel', _handleWheel);
|
|
}
|
|
|
|
void didUnmount() {
|
|
super.didUnmount();
|
|
_stopFling();
|
|
}
|
|
|
|
bool scrollBy(double scrollDelta) {
|
|
var newScrollOffset = scrollCurve.apply(_scrollOffset, scrollDelta);
|
|
if (newScrollOffset == _scrollOffset)
|
|
return false;
|
|
setState(() {
|
|
_scrollOffset = newScrollOffset;
|
|
});
|
|
return true;
|
|
}
|
|
|
|
void _scheduleFlingUpdate() {
|
|
_flingAnimationId = sky.window.requestAnimationFrame(_updateFling);
|
|
}
|
|
|
|
void _stopFling() {
|
|
if (_flingAnimationId == null)
|
|
return;
|
|
sky.window.cancelAnimationFrame(_flingAnimationId);
|
|
_flingCurve = null;
|
|
_flingAnimationId = null;
|
|
}
|
|
|
|
void _updateFling(double timeStamp) {
|
|
double scrollDelta = _flingCurve.update(timeStamp);
|
|
if (!scrollBy(scrollDelta))
|
|
return _stopFling();
|
|
_scheduleFlingUpdate();
|
|
}
|
|
|
|
void _handleScrollUpdate(sky.GestureEvent event) {
|
|
scrollBy(-event.dy);
|
|
}
|
|
|
|
void _handleFlingStart(sky.GestureEvent event) {
|
|
setState(() {
|
|
_flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
|
|
_scheduleFlingUpdate();
|
|
});
|
|
}
|
|
|
|
void _handleFlingCancel(sky.GestureEvent event) {
|
|
_stopFling();
|
|
}
|
|
|
|
void _handleWheel(sky.WheelEvent event) {
|
|
scrollBy(-event.offsetY);
|
|
}
|
|
}
|