RecyclerView + HidingScrollListener + 加载更多

RecyclerView + HidingScrollListener + Load More

我将隐藏滚动侦听器与 recyclerview 结合使用。当我向下滚动 recyclerview 并释放滚动条时,如果加载更多内容并向适配器添加新内容并插入项目范围,我之前添加的行或新添加的行不响应点击。但是当我再次滚动一点时,我所有的点击尝试都有效。

这是我的 HidingScrollListener:

public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {

   private static final float HIDE_THRESHOLD = 10;
   private static final float SHOW_THRESHOLD = 70;

   private int                 mToolbarOffset   = 0;
   private boolean             mControlsVisible = true;
   private int                 mToolbarHeight;
   private int                 mTotalScrolledDistance;
   private int                 previousTotal    = 0;
   private boolean             loading          = true;
   private int                 visibleThreshold = 4;
   int                         firstVisibleItem, visibleItemCount, totalItemCount;
   private LinearLayoutManager layoutManager;

   public HidingScrollListener(Context context, LinearLayoutManager layoutManager) {
      mToolbarHeight = Tools.getFooterHeight(context);
      this.layoutManager = layoutManager;
   }

   @Override
   public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
      super.onScrollStateChanged(recyclerView, newState);

      if (newState == RecyclerView.SCROLL_STATE_IDLE) {
         if (mTotalScrolledDistance < mToolbarHeight) {
            setVisible();
         }
         else {
            if (mControlsVisible) {
               if (mToolbarOffset > HIDE_THRESHOLD) {
                  setInvisible();
               }
               else {
                  setVisible();
               }
            }
            else {
               if ((mToolbarHeight - mToolbarOffset) > SHOW_THRESHOLD) {
                  setVisible();
               }
               else {
                  setInvisible();
               }
            }
         }
      }

   }

   @Override
   public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
      super.onScrolled(recyclerView, dx, dy);

      clipToolbarOffset();
      onMoved(mToolbarOffset);

      if ((mToolbarOffset < mToolbarHeight && dy > 0) || (mToolbarOffset > 0 && dy < 0)) {
         mToolbarOffset += dy;
      }
      if (mTotalScrolledDistance < 0) {
         mTotalScrolledDistance = 0;
      }
      else {
         mTotalScrolledDistance += dy;
      }
      // for load more
      visibleItemCount = recyclerView.getChildCount();
      totalItemCount = layoutManager.getItemCount();
      firstVisibleItem = layoutManager.findFirstVisibleItemPosition();

      if (loading) {
         if (totalItemCount > previousTotal) {
            loading = false;
            previousTotal = totalItemCount;
         }
      }
      if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
         // End has been reached
         // Do something

         loading = true;
         onLoadMore();
      }
   }

   private void clipToolbarOffset() {
      if (mToolbarOffset > mToolbarHeight) {
         mToolbarOffset = mToolbarHeight;
      }
      else if (mToolbarOffset < 0) {
         mToolbarOffset = 0;
      }
   }

   private void setVisible() {
      if (mToolbarOffset > 0) {
         onShow();
         mToolbarOffset = 0;
      }
      mControlsVisible = true;
   }

   private void setInvisible() {
      if (mToolbarOffset < mToolbarHeight) {
         onHide();
         mToolbarOffset = mToolbarHeight;
      }
      mControlsVisible = false;
   }

   public abstract void onMoved(int distance);

   public abstract void onShow();

   public abstract void onHide();

   public abstract void onLoadMore();
}

onLoadMore()

mAdapter.notifyItemRangeInserted(size, data.size());

我不明白为什么会这样。这很奇怪。谢谢。

关键是当我尝试使用 RecyclerViewAdapternotifyItemRangeChanged() 方法时,我通知了错误的范围。

这会导致阻塞 Ui 线程,因此在我中断 ui 线程之前我无法在 onClick 上执行任何操作。

当我为通知适配器设置有效的项目范围时,这个问题得到了解决。

希望我的回答能对大家有所帮助。

正确的调用如下:

mAdapter.notifyItemRangeChanged(size+1, data.size());