android 使用scrollToPosition时未调用RecyclerView on Scrolled

xfb7svmp  于 2023-03-16  发布在  Android
关注(0)|答案(4)|浏览(245)

我有这样的RecyclerView.OnScrollListener

findViewById(R.id.button_scroll_to_position).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        mLinearLayoutManager.scrollToPositionWithOffset(2,0);
    }
}); 

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        Log.i("TAG", "scroll " + dy);
    }
});

ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 7; i++) {
    list.add("" + i);
}
mRecyclerView.setAdapter(new SimpleRVAdapter(list));
mLinearLayoutManager.scrollToPositionWithOffset(2,0);

然而,在某些情况下,onScrolled不调用事件RecyclerView已滚动(使用scrollToPositionWithOffset)。
我知道原因是当我们使用scrollToPositionWithOffset(或scrollToPosition)时onScrolled仅在firstVisibleItemlastVisibleItem改变时调用.您可以在演示中看到(如果firstVisibleItem=2和lastVisibleItem=5 =〉onScrolled未被调用,firstVisibleItem=2和lastVisibleItem=6 =〉onScrolled将被调用)
使用scrollToPosition时,是否有任何技巧或变通方法可以始终接收onScrolled

任何帮助或建议将不胜感激。

0h4hbjxa

0h4hbjxa1#

我发现
如果RecyclerView被滚动(通过使用scrollToPosition),而firstVisibleItemlastVisibleItem不改变不调用RecyclerView.OnScrollListener,但调用View.OnLayoutChangeListener
因此,现在我使用OnScrollListenerOnLayoutChangeListener来监听RecyclerView滚动。
我仍在寻找更好的解决方案

nbnkbykc

nbnkbykc2#

当你调用scrollToPosition()时,滚动从未调用。

来自文档

滚动到某个位置的便利方法。RecyclerView不实现滚动逻辑,而是转发对scrollToPosition(int)的调用
因此scrollToPosition(int)没有实现滚动逻辑。
如需了解更多信息,请查看此链接。https://developer.android.com/reference/android/support/v7/widget/循环视图。

czq61nw1

czq61nw13#

我知道我是在让线坏死,但万一有人像我一样碰到它...
如果您不关心动画用途:

recyclerView.smoothScrollToPosition(position);

它会触发

OnScrollListener.onScrolled(RecyclerView recyclerView, int dx, int dy)
wkyowqbh

wkyowqbh4#

您可以尝试使用OnGlobalLayoutListener来修复此问题。OnGlobalLayoutListener正在修复此问题,方法是直接在RecyclerView上使用scrollBy函数进行少量滚动

(binding.recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(index, offset)
    binding.recyclerView.scrollBy(0, -1)
    val listener = object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            binding.recyclerView.scrollBy(0, 1)
            binding.recyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this)
        }
    }
    binding.recyclerView.viewTreeObserver.addOnGlobalLayoutListener(listener)

感谢Jakub的帮助:)

相关问题