android 如何区分用户滚动和RecyclerView.OnScrollListener中的scrollToPosition()滚动?

2skhul33  于 2022-11-27  发布在  Android
关注(0)|答案(2)|浏览(169)

RecyclerView.OnScrollListeneronScrolled()方法中,我需要能够区分两个不同的scroll事件源:

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

onScrolled()中没有任何参数可以涵盖这一点,是否有一个方法可以区分这一点?
FWIW,我的场景:我有两个RecyclerView小部件。一个是主部件,显示传统的垂直列表。另一个是ViewPager替代部件,允许滑动垂直列表中相同项目的详细信息。在大屏幕环境中,两个RecyclerView小部件将同时可见如果用户滑动寻呼机RecyclerView,我需要更改列表RecyclerView行上的指示符以进行匹配。如果用户点击列表RecyclerView中的行,我需要更新寻呼机RecyclerView中的当前页面。为了侦听寻呼机上的滑动事件,我使用了OnScrollListener,但当 * 我 * 滚动寻呼机以响应列表行单击时,也会触发该事件。

zzoitvuj

zzoitvuj1#

Gabe Sechan关于使用滚动状态更改的建议是一个很好的建议。
不幸的是,没有用于scroll状态的侦听器--它要求您子类化RecyclerView

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

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

1yjd4xko

1yjd4xko2#

如果您使用smoothScrollBy()smoothScrollToPosition(),则接受的答案将不起作用。判断滚动是否来自用户的唯一方法是在用户拖动时设置一个标志,当发生这种情况时,RecyclerView状态将更改为RecyclerView.SCROLL_STATE_DRAGGING。然后,当状态更改为RecyclerView.SCROLL_STATE_IDLE时,您需要清除该标志。

var scrolledByUser = false

rv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrollStateChanged(
        recyclerView: RecyclerView,
        newState: Int
    ) {
        when (newState) {
            RecyclerView.SCROLL_STATE_DRAGGING -> {
                scrolledByUser = true
            }
            RecyclerView.SCROLL_STATE_IDLE -> {
                if (scrolledByUser) {
                    // fromUser
                } else {
                    // from smoothScroll
                }
                scrolledByUser = false
            }
        }
    }
})

相关问题