flutter-draggable-scrollbar icon indicating copy to clipboard operation
flutter-draggable-scrollbar copied to clipboard

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

Open sagarkardani opened this issue 3 years ago • 7 comments

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

sagarkardani avatar May 01 '21 07:05 sagarkardani

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

AlexF1983 avatar May 17 '21 16:05 AlexF1983

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 ?

sagarkardani avatar May 17 '21 16:05 sagarkardani

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 avatar May 17 '21 18:05 AlexF1983

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 :-)

AlexF1983 avatar May 17 '21 18:05 AlexF1983

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

sagarkardani avatar May 17 '21 18:05 sagarkardani

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;
        });
      }
    });
  }

mahdi739 avatar Sep 25 '21 12:09 mahdi739

@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

sagarkardani avatar Sep 27 '21 05:09 sagarkardani