Commit 94c4222f authored by Ali Ghassemi's avatar Ali Ghassemi Committed by GitHub

Few overscroll glow fixes. (#4610)

Fixes #4169 and also now overscroll indicator is dismissed the moment
user scrolls in the opposite direction (#4603) but the bounce overscroll
that happens behind the scene and is clamped in the indicator is still
problematic and needs to be fixed. However these fixes are orthogonal to that.

Also closes #4127 as I verified the timeout feature (reduced the duration
to 500ms to be closer to Android behaviour)
parent d89823be
...@@ -13,7 +13,7 @@ const double _kMaxIndicatorExtent = 64.0; ...@@ -13,7 +13,7 @@ const double _kMaxIndicatorExtent = 64.0;
const double _kMinIndicatorOpacity = 0.0; const double _kMinIndicatorOpacity = 0.0;
const double _kMaxIndicatorOpacity = 0.25; const double _kMaxIndicatorOpacity = 0.25;
const Duration _kIndicatorHideDuration = const Duration(milliseconds: 200); const Duration _kIndicatorHideDuration = const Duration(milliseconds: 200);
const Duration _kIndicatorTimeoutDuration = const Duration(seconds: 1); const Duration _kIndicatorTimeoutDuration = const Duration(milliseconds: 500);
final Tween<double> _kIndicatorOpacity = new Tween<double>(begin: 0.0, end: 0.3); final Tween<double> _kIndicatorOpacity = new Tween<double>(begin: 0.0, end: 0.3);
class _Painter extends CustomPainter { class _Painter extends CustomPainter {
...@@ -132,7 +132,10 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> { ...@@ -132,7 +132,10 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> {
void _hide() { void _hide() {
_hideTimer?.cancel(); _hideTimer?.cancel();
_hideTimer = null; _hideTimer = null;
_extentAnimation.reverse(); // Gaurding _hide() being called while indicator is already animating.
if (!_extentAnimation.isAnimating) {
_extentAnimation.reverse();
}
} }
void _updateState(ScrollableState scrollable) { void _updateState(ScrollableState scrollable) {
...@@ -151,12 +154,15 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> { ...@@ -151,12 +154,15 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> {
void _onScrollUpdated(ScrollableState scrollable) { void _onScrollUpdated(ScrollableState scrollable) {
final double value = scrollable.scrollOffset; final double value = scrollable.scrollOffset;
if ((value < _minScrollOffset || value > _maxScrollOffset) && if (_isOverscroll(value)) {
((value - _scrollOffset).abs() > kPixelScrollTolerance.distance)) { _refreshHideTimer();
_hideTimer?.cancel(); // Hide the indicator as soon as user starts scrolling in the reverse direction of overscroll.
_hideTimer = new Timer(_kIndicatorTimeoutDuration, _hide); if (_isReverseScroll(value)) {
// Changing the animation's value causes an implicit setState(). _hide();
_extentAnimation.value = value < _minScrollOffset ? _minScrollOffset - value : value - _maxScrollOffset; } else {
// Changing the animation's value causes an implicit setState().
_extentAnimation.value = value < _minScrollOffset ? _minScrollOffset - value : value - _maxScrollOffset;
}
} }
_updateState(scrollable); _updateState(scrollable);
} }
...@@ -166,6 +172,21 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> { ...@@ -166,6 +172,21 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> {
_hide(); _hide();
} }
void _refreshHideTimer() {
_hideTimer?.cancel();
_hideTimer = new Timer(_kIndicatorTimeoutDuration, _hide);
}
bool _isOverscroll(double scrollOffset) {
return (scrollOffset < _minScrollOffset || scrollOffset > _maxScrollOffset) &&
((scrollOffset - _scrollOffset).abs() > kPixelScrollTolerance.distance);
}
bool _isReverseScroll(double scrollOffset) {
final double delta = _scrollOffset - scrollOffset;
return scrollOffset < _minScrollOffset ? delta < 0 : delta > 0;
}
bool _handleScrollNotification(ScrollNotification notification) { bool _handleScrollNotification(ScrollNotification notification) {
if (config.scrollableKey == null || config.scrollableKey == notification.scrollable.config.key) { if (config.scrollableKey == null || config.scrollableKey == notification.scrollable.config.key) {
final ScrollableState scrollable = notification.scrollable; final ScrollableState scrollable = notification.scrollable;
......
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