anchor.diff:    void _onScrollEnded(ScrollableState scrollable) {
       _updateState(scrollable);
       _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) {
  
positive.code: 
    void _onScrollUpdated(ScrollableState scrollable) {
      final double value = scrollable.scrollOffset;
      if ((value < _minScrollOffset || value > _maxScrollOffset) &&
          ((value - _scrollOffset).abs() > kPixelScrollTolerance.distance)) {
        _hideTimer?.cancel();
        _hideTimer = new Timer(_kIndicatorTimeoutDuration, _hide);
        // Changing the animation's value causes an implicit setState().
        _extentAnimation.value = value < _minScrollOffset ? _minScrollOffset - value : value - _maxScrollOffset;
      }
      _updateState(scrollable);
    }
  
negative.code:   void _hide() {
      _hideTimer?.cancel();
      _hideTimer = null;
      // Gaurding _hide() being called while indicator is already animating.
      if (!_extentAnimation.isAnimating) {
        _extentAnimation.reverse();
      }
    }
  
    void _updateState(ScrollableState scrollable) {
  