简体   繁体   English

如何以编程方式检测项目何时在 RecyclerView 中可见?

[英]How to programmatically detect when an item is visible in a RecyclerView?

My Android app has a RecyclerView with PagerSnapHelper.我的 Android 应用程序有一个带有 PagerSnapHelper 的 RecyclerView。 Each item has width and height as match_parent .每个项目的宽度和高度为match_parent Thus, only 1 view item stays on the page.因此,只有 1 个视图项留在页面上。 I am interested in knowing when a particular view item is fully visible to the user.我有兴趣知道特定视图项何时对用户完全可见。 I want to perform some operation on that view.我想对该视图执行一些操作。

More Details更多细节

I am displaying charts in each view item using MpAndroidChart library.我使用MpAndroidChart库在每个视图项中显示图表。 I am also animating those charts.我也在为这些图表制作动画。 But since the RecyclerView loads some view items which are just adjacent to the currently visible view items, the animation happens before the view is even visible to the user.但是由于 RecyclerView 加载了一些与当前可见的视图项相邻的视图项,动画发生在视图对用户可见之前。 Thus, I need a callback method to surely know that a particular view item is visible to the user.因此,我需要一个回调方法来确定某个特定的视图项对用户可见。 So that I can animate my chart at that time.这样我就可以在那个时候为我的图表制作动画。

Code代码

I tried the following way to know for sure what's the currently visible item view.我尝试了以下方法来确定当前可见的项目视图是什么。 But it didn't solve my issue:但这并没有解决我的问题:

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

Edit 1编辑 1

The only known callback method for implementing the logic for each item view of a RecyclerView is onBindViewHolder .为 RecyclerView 的每个项目视图实现逻辑的唯一已知回调方法是onBindViewHolder But the issue is if currently visible item position is (suppose) x, then RecyclerView also loads x+1 in advance so that the scrolling remains smooth.但问题是如果当前可见的项目位置是(假设)x,那么 RecyclerView 也会提前加载 x+1 以便滚动保持平滑。 Due to this, the logic of animating the item view (in my case) is also getting executed before the view is even visible to the user.因此,在视图对用户可见之前,动画项目视图(在我的例子中)的逻辑也会被执行。 Thus, I need a callback method which tells me x position (or) item view is "visible" to the user.因此,我需要一个回调方法来告诉我 x 位置(或)项目视图对用户“可见”。

Any help will be greatly appreciated!任何帮助将不胜感激!

Sorry for answer on Kotlin, I can't check it quickly on Java now.抱歉在 Kotlin 上回答,我现在无法在 Java 上快速检查。 But I hope it is also readable:但我希望它也是可读的:

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

So you just need to find offset for first visible position.所以你只需要找到第一个可见位置的偏移量。 And if it equals 0, then your item showing completely.如果它等于 0,则您的项目完全显示。

use this code:使用此代码:

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

Mumayank please don't forget to post your solution. Mumayank,请不要忘记发布您的解决方案。 I'm facing the same situation 我正面临着同样的情况

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM