android – 我们如何区分用户滚动与scrollToPosition()在RecyclerView.OnScrollListener中滚动?

在我的RecyclerView.OnScrollListener的onScrolled()方法中,我需要能够区分两个不同的滚动事件源:

>用户使用触摸事件滚动RecyclerView
>使用scrollToPosition()滚动RecyclerView的代码

onScrolled()没有参数可以解决这个问题.有这个区别的秘诀吗?

FWIW,我的场景:我有两个RecyclerView小部件.一个是主人,并显示传统的垂直列表.另一个是ViewPager的替代品,允许浏览垂直列表中相同项目的详细信息.在大屏幕环境中,两个RecyclerView小部件将立即可见(主 – 细节模式),我需要保持它们同步.如果用户滑动寻呼机RecyclerView,我需要更改列表中的RecyclerView行以匹配.如果用户点击列表RecyclerView中的一行,我需要更新寻呼机RecyclerView中的当前页面.要在寻呼机上侦听滑动事件,我正在使用OnScrollListener,但是当我滚动寻呼机以响应列表行点击时,也会触发该触发事件.

最佳答案 Gabe Sechan建议使用滚动状态更改是一个很好的建议.

不幸的是,没有滚动状态的监听器 – 它要求你继承RecyclerView.所以,我掀起了一个RecyclerViewEx来为该事件添加一个监听器API:

public class RecyclerViewEx extends RecyclerView {
  interface OnScrollStateChangedListener {
    void onScrollStateChanged(int state);
  }

  final private ArrayList<OnScrollStateChangedListener> listeners=new ArrayList<>();

  public RecyclerViewEx(Context context) {
    super(context);
  }

  public RecyclerViewEx(Context context, @Nullable
    AttributeSet attrs) {
    super(context, attrs);
  }

  public RecyclerViewEx(Context context, @Nullable AttributeSet attrs,
                        int defStyle) {
    super(context, attrs, defStyle);
  }

  public void addOnScrollStateChangedListener(OnScrollStateChangedListener listener) {
    listeners.add(listener);
  }

  public void removeOnScrollStateChangedListener(OnScrollStateChangedListener listener) {
    listeners.remove(listener);
  }

  @Override
  public void onScrollStateChanged(int state) {
    super.onScrollStateChanged(state);

    for (OnScrollStateChangedListener listener : listeners) {
      listener.onScrollStateChanged(state);
    }
  }
}

scrollToPosition()不会触发滚动状态更改,而用户滑动则会触发.所以,我可以通过这种方式区分这两种情况.

rve.addOnScrollStateChangedListener(
  scrollState -> {
    if (scrollState==RecyclerView.SCROLL_STATE_IDLE) {
      // do something cool, now that the user swipe is complete
    }
  });

鉴于此,我不需要标志或任何其他状态,这有助于保持逻辑更简单.

点赞