停止滚动中间的滚动视图

我有很多内容的滚动视图。 现在,当用户做了一个或一个向下滚动,我希望滚动视图停止在一个特定的视图位置,我正在做一些animation,然后用户可以再次扔掉或向下滚动。

我已经尝试了在这里提到的禁用scrollview,但它只有当scrollview完全停止,不能停止在一个半决赛时停用。

当某个视图位置或某个y值达到时,有什么办法可以阻止滚动视图?

Solutions Collecting From Web of "停止滚动中间的滚动视图"

我遇到了同样的问题,我的解决scheme是。

listView.smoothScrollBy(0,0) 

这将停止滚动。

一种方法可能是使用smoothScrollToPosition ,它可以停止任何现有的滚动动作。 请注意,此方法需要API级别> = 8(Android 2.2,Froyo)。

请注意,如果当前位置离想要的位置很远,那么平滑的滚动将需要相当长的时间,看起来有点生涩(至less在我的Android 4.4 KitKattesting中)。 我还发现,调用setSelection和smoothScrollToPosition的组合有时可能会导致位置稍微“错过”,这只有在当前位置非常接近所需位置时才会发生。

在我的情况下,当用户按下一个button时,我希望我的列表跳转到顶部 (位置= 0)(这与您的用例略有不同,所以您需要根据需要进行调整)。

我用下面的方法来

 private void smartScrollToPosition(ListView listView, int desiredPosition) { // If we are far away from the desired position, jump closer and then smooth scroll // Note: we implement this ourselves because smoothScrollToPositionFromTop // requires API 11, and it is slow and janky if the scroll distance is large, // and smoothScrollToPosition takes too long if the scroll distance is large. // Jumping close and scrolling the remaining distance gives a good compromise. int currentPosition = listView.getFirstVisiblePosition(); int maxScrollDistance = 10; if (currentPosition - desiredPosition >= maxScrollDistance) { listView.setSelection(desiredPosition + maxScrollDistance); } else if (desiredPosition - currentPosition >= maxScrollDistance) { listView.setSelection(desiredPosition - maxScrollDistance); } listView.smoothScrollToPosition(desiredPosition); // requires API 8 } 

在我的button的动作处理程序中,我按如下所示调用它

  case R.id.action_go_to_today: ListView listView = (ListView) findViewById(R.id.lessonsListView); smartScrollToPosition(listView, 0); // scroll to top return true; 

以上并不直接回答你的问题,但是如果你可以检测到当前位置是在你想要的位置还是在你的位置附近,那么也许你可以使用smoothScrollToPosition来停止滚动。

您需要禁用ScrollView处理的投掷操作。 为了做到这一点,只需重写ScrollView方法并评论super.fling() 。 让我知道这个是否奏效 !

 public class CustomScrollView extends ScrollView { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public void fling (int velocityY) { /*Scroll view is no longer gonna handle scroll velocity. * super.fling(velocityY); */ } } 

以及即时通讯实际使用这种方法:

  list.post(new Runnable() { @Override public void run() { list.smoothScrollToPositionFromTop(arg2, 150); } }); 

我正试图达到类似的情况。 我有一个部分的解决scheme:

我设法通过覆盖onScrollChanged ,然后调用smoothScrollTo来停止在特定y坐标的ScrollView。 我允许用户继续向下滚动,保持一个布尔值,表示这是否是第一次投掷/拖动。 从下往上滚动也是一样 – 我再次停止滚动。 然后允许用户继续向上滚动。

代码看起来像这样:

 boolean beenThereFromTop = false; boolean beenThereFromBottom = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView); scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { TextView whereToStop = (TextView) findViewById(R.id.whereToStop); final int y = whereToStop.getBottom(); int scrollY = scrollView.getScrollY(); // manage scrolling from top to bottom if (scrollY > y) { if (!beenThereFromTop) { beenThereFromTop = true; scrollView.post(new Runnable() { @Override public void run() { scrollView.smoothScrollTo(0, y); } }); } } if (scrollY < y && beenThereFromTop) { beenThereFromTop = false; } // manage scrolling from bottom to top if (scrollY < y) { if (!beenThereFromBottom) { beenThereFromBottom = true; scrollView.post(new Runnable() { @Override public void run() { scrollView.smoothScrollTo(0, y); } }); } } if (scrollY > y && beenThereFromBottom) { beenThereFromBottom = false; } } }); } 

要停止在一个特定点的投掷,只需打电话

 fling(0) 

如果你只关心fl this,这是在我的opionon中这样做的最合理的方式,因为velosityY被设置为0,从而立即停止一掷。

这里是一个方法的javadoc:

 /** * Fling the scroll view * * @param velocityY The initial velocity in the Y direction. Positive * numbers mean that the finger/cursor is moving down the screen, * which means we want to scroll towards the top. */