我们如何在scrolllerView.OnScrollListener中区分用户滚动和scrollToPosition()滚动?

时间:2018-02-06 18:33:51

标签: android android-recyclerview

onScrolled()的{​​{1}}方法中,我需要能够区分两种不同的滚动事件来源:

  • 用户使用触摸事件滚动RecyclerView.OnScrollListener
  • 使用RecyclerView
  • 滚动RecyclerView的代码

scrollToPosition()没有任何参数可以涵盖这一点。是否有制作这种区别的方法?

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

1 个答案:

答案 0 :(得分:1)

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
    }
  });

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