【问题标题】:How to programmatically detect when an item is visible in a RecyclerView?如何以编程方式检测项目何时在 RecyclerView 中可见?
【发布时间】:2018-06-19 10:06:34
【问题描述】:

我的 Android 应用有一个带有 PagerSnapHelper 的 RecyclerView。每个项目的宽度和高度为match_parent。因此,只有 1 个视图项保留在页面上。我有兴趣了解特定视图项何时对用户完全可见。我想对该视图执行一些操作。

更多详情

我使用MpAndroidChart 库在每个视图项中显示图表。我也在为这些图表制作动画。但是由于 RecyclerView 加载了一些与当前可见视图项相邻的视图项,因此动画在视图对用户可见之前就发生了。因此,我需要一个回调方法来确定用户可以看到特定的视图项。这样我就可以在那时为我的图表制作动画。

代码

我尝试了以下方法来确定当前可见的项目视图是什么。但这并没有解决我的问题:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (newState != RecyclerView.SCROLL_STATE_DRAGGING) {
            View centerView = snapHelper.findSnapView(linearLayoutManager);
            BarChart barChart = centerView.findViewById(R.id.barChart);
            barChart.animateXY(ChartUtil.TIME, ChartUtil.TIME);
        }
    }
});

编辑 1

为 RecyclerView 的每个项目视图实现逻辑的唯一已知回调方法是 onBindViewHolder。但问题是,如果当前可见的项目位置是(假设)x,那么 RecyclerView 也会提前加载 x+1,以便滚动保持平滑。因此,动画项目视图的逻辑(在我的例子中)也在视图对用户可见之前被执行。因此,我需要一个回调方法,告诉我 x 位置(或)项目视图对用户“可见”。

任何帮助将不胜感激!

【问题讨论】:

  • 阅读您的问题后,我觉得您想在获取特定视图的数据后在回收视图中显示该项目?对吗?
  • @ShravanJain 不,我有预先的数据。数据的大小保持固定。但是,由于 RecyclerView 在可见项目的左侧/右侧加载了更多项目,然后才真正可见,因此图表(在 recyclerView 的项目视图内)在用户实际可见之前被加载并动画。因此,我想要一种方法来了解用户是否可以看到项目视图,以便在那一刻我可以为图表设置动画。
  • 好的。因此,您必须有一个类,您可以在其中实现特定项目的回收视图的视图。您可以轻松地将其逻辑放在那里。
  • 唯一已知的用于为 recyclerView 的每个项目视图实现我的逻辑的回调方法是 onBindViewHolder。但问题是如果当前可见的项目位置是(假设)x,那么 recyclerView 也会提前加载 x+1 以便滚动保持平滑。因此,我的项目视图动画逻辑也在视图对用户可见之前执行。因此,我需要一个回调方法来告诉我特定视图是否对用户“可见”。

标签: java android android-recyclerview mpandroidchart


【解决方案1】:

抱歉,Kotlin 上的答案,我现在无法在 Java 上快速检查它。但我希望它也是可读的:

recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)
        if (layoutManager.findViewByPosition(layoutManager.findFirstVisibleItemPosition()).y == 0) {
            // Do what you need
        }
    }
})

所以你只需要找到第一个可见位置的偏移量。如果它等于 0,那么您的项目完全显示。

【讨论】:

  • 没有。请完整阅读我的问题。我已经尝试过这种方法。它不工作。如果您认为我在当前的实施中遗漏了一些指示,请您在回答中添加更多内容。
  • 感谢您的回答,我将不得不更多地考虑您的解决方案,然后告诉您它是否有效。请给我一点时间。
  • @MayankMohanUpadhyay 没关系。如果它对您有用,请接受答案。或者,如果您有任何问题,请随时提出。
  • 不,这对我不起作用。我今天找到了一个可行的解决方案。我会发布它。
  • 不,还没有。由于没有答案,我暂停了这项工作。将再次搜索。
【解决方案2】:

使用此代码:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    super.onScrolled(recyclerView, dx, dy);
    
    LinearLayoutManager linearLayoutManager= (LinearLayoutManager) recyclerView.getLayoutManager();
    
    linearLayoutManager.findFirstCompletelyVisibleItemPosition();
    
    linearLayoutManager.findLastCompletelyVisibleItemPosition();
    
    
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 2020-10-30
    • 1970-01-01
    • 2015-04-11
    • 2015-03-06
    • 2018-04-28
    相关资源
    最近更新 更多