fluttercommunity / flutter-draggable-scrollbar

Draggable Scrollbar - A scrollbar that can be dragged for quickly navigation through a vertical list. Additional option is showing label next to scrollthumb with information about current item. Maintainer: @marica27
https://pub.dev/packages/draggable_scrollbar
MIT License
441 stars 77 forks source link

Thumb position is incorrect on top and bottom when BouncingScrollPhysics() bounces the widget #49

Open sagarkardani opened 3 years ago

sagarkardani commented 3 years ago

A big thanks for creating such a nice library...

Whenever physics is set to physics: BouncingScrollPhysics() inside ListView.builder() then thumb position is incorrect while bounce.

However position is incorrect only after scroll bounces. Afterwards if the thumb is dragged manually up to the top or bottom then it automatically goes back to normal position.

https://user-images.githubusercontent.com/60609139/116781704-53a9e880-aaa2-11eb-8745-acde1f664614.mp4

Regards Sagar

AlexF1983 commented 3 years ago

i have the same problem on ios/iphone but not on android/samsung

sagarkardani commented 3 years ago

i have the same problem on ios/iphone but not on android/samsung

I have also checked in both and I am facing issue in both andoid and iOS 🤔.

How you have overcome the issue in android ?

AlexF1983 commented 3 years ago

well sorry i thought the bouncing thing is only on ios because its a normal behavior in every app on my iphone i never saw something like that on android (not in 8.0 on real device, not in 11.0 on emulator)

and in my case i only use "physics: ScrollPhysics()," and have the same problem and if i use BouncingScrollPhysics on android then my listview isn't bouncing

so: i can't switch it off on ios and i can't switch it on on android but at the end it works fine with the normal ScrollBar so it should be the package and ios, in my opinion

let me research and test a little bit, maybe there is something wrong with my environment etc.

AlexF1983 commented 3 years ago

if i use ClampingScrollPhysics and the listview/gridview is a child of the scrollbar then the listview isn't bouncing and i don't have the problem but one problem is that on some places in my app the listview is not a child of the scrollbar or respectively doesn't have the same controller etc. so it does not work if i solve the last problem, then this issue is no longer relevant for me because i switched off the bouncing :-)

sagarkardani commented 3 years ago

Yes, the issue is only with BouncingScrollPhysics() and not with ClampingScrollPhysics(). 👍

mahdi739 commented 3 years ago

Hi. Go to the changePosition method and add these 4 lines at the end:

changePosition(ScrollNotification notification) {
    if (_isDragInProcess) {
      return;
    }

    setState(() {
      if (notification is ScrollUpdateNotification) {
        _barOffset += getBarDelta(
          notification.scrollDelta!,
          barMaxScrollExtent,
          viewMaxScrollExtent,
        );

        if (_barOffset < barMinScrollExtent) {
          _barOffset = barMinScrollExtent;
        }
        if (_barOffset > barMaxScrollExtent) {
          _barOffset = barMaxScrollExtent;
        }

        _viewOffset += notification.scrollDelta!;
        if (_viewOffset < widget.controller.position.minScrollExtent) {
          _viewOffset = widget.controller.position.minScrollExtent;
        }
        if (_viewOffset > viewMaxScrollExtent) {
          _viewOffset = viewMaxScrollExtent;
        }
      }

      if (notification is ScrollUpdateNotification ||
          notification is OverscrollNotification) {
        if (_thumbAnimationController.status != AnimationStatus.forward) {
          _thumbAnimationController.forward();
        }

       //Add these lines:
        if (notification.metrics.pixels < notification.metrics.minScrollExtent)
          _barOffset = barMinScrollExtent;
        if (notification.metrics.pixels > notification.metrics.maxScrollExtent)
          _barOffset = barMaxScrollExtent;
       //

        _fadeoutTimer?.cancel();
        _fadeoutTimer = Timer(widget.scrollbarTimeToFade, () {
          _thumbAnimationController.reverse();
          _labelAnimationController.reverse();
          _fadeoutTimer = null;
        });
      }
    });
  }
sagarkardani commented 3 years ago

@mahdi739

Thanks for reply...

I was able to achieve the behaviour by adding below lines, but have forgotten to update here.

if (widget.controller.offset < viewMinScrollExtent) {
   _barOffset = barMinScrollExtent;
}
if (widget.controller.offset > viewMaxScrollExtent) {
   _barOffset = barMaxScrollExtent;
}

What you have suggested is also seems correct. Technically I don't know which one is better but at present we have got the desired behaviour.

:slightly_smiling_face:

Regards, Sagar