等待RecyclerView滚动到特定位置

3

我正在使用RecyclerView,需要选择其中的最后一项。

首先滚动到RecyclerView最后一项,然后调用所选项目的performClick()方法。

以下是代码:

int latestPostIndex = reactionsListAdapter.getItemCount() - 1;
rvReactionsList.scrollToPosition(latestPostIndex);
rvReactionsList.getChildAt(latestPostIndex).performClick();

latestPostIndex已正确填充。问题在于performClick在滚动完成之前被调用,因此应用程序崩溃。

我该如何使performClick()等待scrollToPosition()完成后再执行?


performClick()难道不是做这个的吗?但问题不在此。问题是当点击项目时,performClick() /code会在RecyclerView滚动完成之前触发,也就是说,索引latestPostIndex处的对象为空,因此应用程序会崩溃。编辑:我还尝试了添加代码而不是performClick()。它有相同的问题。 - Chandan Pednekar
2个回答

6
您可以为您的RecyclerView分配一个RecyclerView.OnScrollListener并监听onScrollStateChanged,等待滚动结束:
int latestPostIndex = reactionsListAdapter.getItemCount() - 1;
rvReactionsList.scrollToPosition(latestPostIndex);
rvReactionsList.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if(newState == RecyclerView.SCROLL_STATE_IDLE 
            && linearLayoutManager.findLastVisibleItemPosition() == latestPostIndex)
            linearLayoutManager.findViewByPosition(latestPostIndex).performClick();

    }
});

P.S:不要忘记将rvReactionsList.getChildAt(latestPostIndex)替换为linearLayoutManager.findViewByPosition(latestPostIndex),因为getChildAt无法返回RecyclerView的最后一个单元格。


尝试了这段代码,但是没有起作用。仍然出现相同的错误。在一个空对象上调用performClick()方法。 - Chandan Pednekar
更新的答案以更清晰为目标。rvReactionsList.getChildAt(latestPostIndex) 实际上是错误的。 - Keivan Esbati
@KeivanEsbati 我会再试一次使用layoutManager,以确保。 - Chandan Pednekar
1
你的代码可以工作,但只有在我尝试访问最后一个不可见的项目时才能工作。 当我尝试访问可见的recyclerview上的最后一个项目时,该项目未被选中。有什么想法吗? - Chandan Pednekar
当然..忘记了这个..在滚动列表之前,首先检查最后一个项目是否可见=>如果可见,则执行单击操作,否则滚动列表。像这样检查最后一个项目的可见性: if(newState == RecyclerView.SCROLL_STATE_IDLE && linearLayoutManager.findLastVisibleItemPosition() == latestPostIndex) linearLayoutManager.findViewByPosition(latestPostIndex).performClick(); - Keivan Esbati
显示剩余5条评论

1
所选答案存在问题。有时它会滚动,有时它不会滚动。
我没有理解的是 smoothScrollToPosition(index) 或 scrollToPosition(index) 会聚焦 / 选择传递索引的项目。
答案中的解决方法是一种低效的方式,因为它不断检查布尔表达式,而用户并没有滚动列表。
我只需要在 smoothScrollToPosition 后调用 notifyDatasetChanged() 并设置一个名为 currentReactionPos 的索引(它在 onBindView() 方法中使用)。
这是可行的代码。
// Select latest item after items added from server
                final int latestPostIndex = reactionsListAdapter.getItemCount() - 1;
                currentReactionPos = latestPostIndex;
                rvReactionsList.smoothScrollToPosition(latestPostIndex);
                rvReactionsList.getAdapter().notifyDataSetChanged();

很高兴你终于找到了一个完美适合你的方法,但请记住你的问题标题是“等待recyclerview滚动到位置”,你想要的是“在从服务器添加项目后选择最新项目”。你提供的答案可能满足你的用例,但绝不满足这个问题的本意。 - Keivan Esbati

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接