xuelongqy / flutter_easy_refresh

A flutter widget that provides pull-down refresh and pull-up load.
https://xuelongqy.github.io/flutter_easy_refresh/
MIT License
3.89k stars 633 forks source link

当hitOver和infiniteHitOver为true时,加载更多内容后无法停止回弹动画 #831

Open hao-feng opened 4 months ago

hao-feng commented 4 months ago

使用example项目, 修改nested_scroll_view.dart 中的header和footer hitOver: true, infiniteHitOver: true 模拟比较快的请求,修改 Future.delayed(const Duration(milliseconds: 300) 滑动列表到底部,在回弹的过程中,加载的请求返回了,单列表仍然在继续执行回弹动画 附件为修改后的nested_scroll_view.dart nested_scroll_view.dart.zip

bug效果如下

https://github.com/xuelongqy/flutter_easy_refresh/assets/10826587/400ce9cf-15bb-44c1-9676-fe22138cd317

xuelongqy commented 4 months ago

设计如此吧。回弹动画是Flutter自身的,打断也会很奇怪。几种解决办法,1.设置infiniteOffset,在没有滑到底部就加载;2.不设置infiniteHitOver和hitOver;3.增加异步延时。倾向于第二种方法,因为这个回弹并不会提升用户体验,其次呢一定要去解决这个问题,纯属于开发者内耗,没有必要的。

hao-feng commented 4 months ago

怎么会是设计如此呢,随便找一个 ios app 的回弹都不会是这样的,都是会打断回弹并且往相反方向滚动(如果还有速度的话) 我来翻译一下上边的解决方案:1和 3 都是降低了触发问题的概率,一个是说到底部之前就完成请求,一个是说尽量等回弹结束了再完成请求🥹 2 的意思是说别用 ios 的列表滚动效果了

xuelongqy commented 4 months ago

是的,在我看来无限滚动没必要使用ios的回弹效果,所以默认到底部是无法越界的。如果你在Flutter中找到在非用户事件的情况下能够判断列表变化,并能阻止滚动的方法,请告诉我,或者提交pr。短时间内,我没有时间去研究这个。

hao-feng commented 4 months ago
extension ExtensionScrollController on ScrollController {
  void stopScrollingIfBouncing() {
    const double footerHeight = 50;
    if (position.pixels - footerHeight > position.maxScrollExtent) {
      // 获取当前的滚动位置
      final double currentScrollPosition = position.pixels;
      // 向下滚动
      animateTo(currentScrollPosition + 1,
          duration:
              Duration(milliseconds: 1),
          curve: Curves.decelerate);
    }
  }
}

如果有其他人遇到类似问题的话,我临时的解决方案是在scrollview高度变化时调用如上方法,可以打断当前的回弹动画,并继续正常的向下滚动滑动