flutter/examples/fn/widgets/fixedheightscrollable.dart
Eric Seidel 2a9c2c40bf Make stocksapp.dart almost pass the dart analyzer.
To test:
sky/tools/shelldb analyze sky/examples/stocks-fn/stocksapp.dart

It prints 600+ warnings about the "native" keyword, and after
this change only a couple warnings about missing library names
which I don't fully understand.

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/987613002
2015-03-05 16:52:14 -08:00

128 lines
2.9 KiB
Dart

part of widgets;
abstract class FixedHeightScrollable extends Component {
static Style _style = new Style('''
overflow: hidden;
position: relative;
will-change: transform;'''
);
static Style _scrollAreaStyle = new Style('''
position:relative;
will-change: transform;'''
);
double itemHeight;
double height;
double minOffset;
double maxOffset;
double _scrollOffset = 0.0;
FlingCurve _flingCurve;
int _flingAnimationId;
FixedHeightScrollable({
Object key,
this.itemHeight,
this.height,
this.minOffset,
this.maxOffset
}) : super(key: key) {}
List<Node> renderItems(int start, int count);
Node render() {
int drawCount = (height / itemHeight).round() + 1;
double alignmentDelta = -_scrollOffset % itemHeight;
if (alignmentDelta != 0.0) {
alignmentDelta -= itemHeight;
}
double drawStart = _scrollOffset + alignmentDelta;
int itemNumber = (drawStart / itemHeight).floor();
var transformStyle =
'transform: translateY(${(alignmentDelta).toStringAsFixed(2)}px)';
var items = renderItems(itemNumber, drawCount);
return new Container(
style: _style,
children: [
new Container(
style: _scrollAreaStyle,
inlineStyle: transformStyle,
children: items
)
]
)
..events.listen('gestureflingstart', _handleFlingStart)
..events.listen('gestureflingcancel', _handleFlingCancel)
..events.listen('gesturescrollupdate', _handleScrollUpdate)
..events.listen('wheel', _handleWheel);
}
void willUnmount() {
_stopFling();
}
bool _scrollBy(double scrollDelta) {
var newScrollOffset = _scrollOffset + scrollDelta;
if (minOffset != null && newScrollOffset < minOffset) {
newScrollOffset = minOffset;
} else if (maxOffset != null && newScrollOffset > maxOffset) {
newScrollOffset = maxOffset;
}
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);
}
}