如何在添加子项时正确地继续 ScrollView 的滚动?

12

背景:我有一个ScrollView,在它滑动的过程中可能会添加子元素到其内容视图中。因为滑动是在添加这些子元素之前根据ScrollView内容的高度配置的,如果添加了这些子元素,那么滑动就会停止(实际上还会因为超出滚动而向后滚动一点),即使它还没有滚动到内容的底部。

我可以使用#fling(int velocity)重新启动滚动,但我找不到获取当前滚动速度或停止当前滚动的方法。有什么建议吗?


我建议像处理数组一样处理这个问题。 在列表中始终放入两倍或更多的元素,以满足您的需求。 您现在没有的元素的后一半是空的。 如果要添加元素,请不要添加它,而是使用新数据填充下一个空元素。 如果列表滚动到最后一个已填充的元素,请停止滚动。 这样,您将始终拥有正在进行的滚动。 - JacksOnF1re
@Foxichu,我也遇到了问题,请分享一些代码来解决这个问题。正如你所提到的,你使用嵌套滚动视图代码解决了这个问题。请分享一下。提前致谢。 - gireesh Chanti
2个回答

8

回答提示中的问题:

  • 没有API可以获取ScrollView的当前速度。
  • 您可以通过谨慎处理触摸事件来停止当前的飞滑,具体方法请参考之前的SO post

查看ScrollView源代码,它使用OverScroller来处理飞滑事件。有两种方法可以解决这个问题:

  1. 使用反射访问ScrollView中的mScroller私有字段。一旦访问到,您可以通过其公共API获取当前速度:public float getCurrVelocity(); 使用反射并不理想,因为您需要担心它在Android版本之间的兼容性问题,但是一个简单的隔离用法可以相对高效。
  2. 覆盖ScrollView中的fling()方法并实例化OverScroller以跟踪滚动。如果一切顺利,您的OverScroller将始终处于与ScrollView中的OverScroller相同的状态。

类似这样:

@Override
public void fling(int velocityY)
{
    // Pass through fling to parent
    super.fling(velocityY);

    // Keep track of velocity using our own Overscoller instance
    mOurOverscroller = mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
    Math.max(0, bottom - height), 0, height/2);
}

1
我最终选择的替代方法是:从支持库中分叉(即复制)NestedScrollView代码到一个新的类,并根据需要进行编辑。 - Foxichu

2

我用@Override fling方法解决了类似的问题。如果你在ScrollViewNoFling类中重写fling方法,但不在此方法中调用super.fling,那么你将得到一个未处理fling的scrollView

@Override
public void fling (int velocity)
{
    /*Scroll view is no longer going to handle scroll velocity.
     * super.fling(velocity);
    */
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接