【问题标题】:Wait until recyclerview has scrolled to position等到 recyclerview 滚动到位置
【发布时间】:2018-04-23 10:28:05
【问题描述】:

我正在使用 recyclerview,我必须选择 recyclerview 中的最后一项。

我首先滚动到recyclerview,然后在选定的项目上调用performClick()方法。

这里是代码。

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

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

如何让 performClick() 等到 scrollToPosition() 完成?

【问题讨论】:

  • 这不就是 performClick() 的作用吗?另外,这不是问题。问题是在 recyclerview 滚动完成之前单击项目触发的 performClick() /code。这意味着索引 latestPostIndex 处的对象为空,因此应用程序崩溃。编辑:我也尝试添加代码而不是 performClick()。它有同样的问题。

标签: android android-recyclerview


【解决方案1】:

您可以将RecyclerView.OnScrollListener 分配给您的RecyclerView 并收听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()。
  • 更新了答案以更清晰。 rvReactionsList.getChildAt(latestPostIndex) 实际上是错误的..
  • @KeivanEsbati 我会用 layoutManager 再试一次以确保。
  • 呃.. @pskink 我有一个包含许多项目的水平列表。从水平列表中选择一个项目时,在 viewpager 中选择了相同的项目。这就是为什么我想在我想要的项目上调用 performClick。因此它会自动在 viewpager 上选择适当的项目。基本上我想像用户通常做的那样模拟点击。如您所述,我该如何处理数据模型?
  • 您的代码有效,但仅当我尝试访问不可见的最后一项时。当我尝试访问在 recyclerview 上可见的最后一个项目时,该项目未被选中。知道为什么吗?
【解决方案2】:

选择的答案有问题。有时它会滚动,有时却没有。

我不明白的是 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 滚动到位置”并且您想要“在添加项目后选择最新项目服务器”。您提供的答案可能会满足您的用例,但绝不会满足这个问题的含义..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 2018-10-26
相关资源
最近更新 更多