Android:onScrollStateChanged SCROLL_STATE_IDLE有时不会触发

时间:2011-11-15 17:35:51

标签: android listview scroll

我遇到了一些问题。我在做什么:我有一个ListView,里面有一些图像。为了使滚动更顺畅,我已禁用滚动时显示的图像。现在Android中似乎有一个bug,有时会导致滚动状态不会从SCROLL_STATE_FLING变回SCROLL_STATE_IDLE,这会导致我的图像不再显示。

我的第一个想法是设置一个onTouchListener并检查我何时获得ACTION_UP,但这没有用,因为之后显然设置了SCROLL_STATE_FLING状态。所以现在我认为我可以在设置SCROLL_STATE_FLING状态时启动计时器,并在一段时间后检查状态是否仍处于fling模式然后使我的视图无效。但我认为这不是一个很好的解决方案。

有没有人对如何做到这一点有更好的了解?我看过this回复,但我需要API级别的解决方案< 9(加上它有时也会在没有过度滚动时发生)

这是我的代码:

    mList.setOnScrollListener(new OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE);
            Log.i(this, "scrollStateChanged" + scrollState);
            if (scrollState == SCROLL_STATE_IDLE) {
                mList.invalidateViews();
            }
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        }
    });

谢谢, 玛利亚

3 个答案:

答案 0 :(得分:17)

我有同样的问题,所以我的解决方案只是检测滚动视图位置是否已到达最后一页,在这种情况下总是加载图像而不管滚动状态(因为问题似乎总是发生在用户挥动时到列表视图的末尾)。所以修改你的代码:

mList.setOnScrollListener(new OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE);
        Log.i(this, "scrollStateChanged" + scrollState);

        int first = view.getFirstVisiblePosition();
        int count = view.getChildCount();

        if (scrollState == SCROLL_STATE_IDLE || (first + count > mListAdapter.getCount()) ) {
            mList.invalidateViews();
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    }
});

答案 1 :(得分:1)

我遇到了同样的问题,并在bug list上发布了一个解决方法:

  

对于任何仍然遇到此问题的人(就像我上周一样)a   对我有用的解决方法如下:如果android SDKInt == 7   在onTouchListener

上设置(Abs)ListView      

onTouchListener事件操作为OnTouch时   MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL你强迫   一个onScrollStateChanged,第一个SCROLL_STATE_FLING,然后是。{   SCROLL_STATE_IDLE

     

代码示例:在onCreate

  if(androidSDKInt <= 7){
      listViewDateSelector.setOnTouchListener(new FingerTracker(onScrollListener));       }
     

然后添加一个私有类:

  private class FingerTracker implements View.OnTouchListener {
      private OnScrollListener myOnScrollListener;

      public FingerTracker(OnScrollListener onScrollListener){
          myOnScrollListener = onScrollListener;          }

      public boolean onTouch(View view, MotionEvent event) {
          final int action = event.getAction();
          boolean mFingerUp = action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL;
          if (mFingerUp) {
              myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_FLING);
              myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_IDLE);
          }
          return false;           }       }

答案 2 :(得分:1)

我遇到了一个RecyclerView问题。

Jason Burke's answer是正确的,但是我将提供另一种方法来检查您是否在RecyclerView / ListView的开头/结尾。

我在onScrolled中执行此操作,而不是在onScrollStateChanged中进行操作,因为当您滚动/移动到RecyclerView的边缘时,我不相信会收到状态更改事件

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)

        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            updateUi()
        }
    }

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        /* If the user scrolls to the edges of the recyclerview, we can't trust that we get the SCROLL_STATE_IDLE state.
         * Therefore we have to update the view here in onScrolled for these cases
         */
        if (!recyclerView.canScrollVertically(1) || !recyclerView.canScrollVertically(-1)) {
            updateUi()
        }
    }
}

在我来说,它实际上是一个水平的RecyclerView,所以我不得不这样做:

if (!recyclerView.canScrollHorizontally(1) || !recyclerView.canScrollHorizontally(-1)) {
    updateUi()
}