Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

My Android app has a RecyclerView with PagerSnapHelper. Each item has width and height as match_parent. Thus, only 1 view item stays on the page. 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. 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. 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

The only known callback method for implementing the logic for each item view of a RecyclerView is 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. 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.

Any help will be greatly appreciated!

like image 997
mumayank Avatar asked Jun 19 '18 10:06

mumayank


People also ask

How do I know my RecyclerView is visible?

OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super. onScrolled(recyclerView, dx, dy); LinearLayout ll = (LinearLayout) recyclerView. findChildViewUnder(dx, dy); if (ll != null) { TextureVideoView tvv = (TextureVideoView) ll.

How do I know if my RecyclerView is scrolled to the bottom?

In order to detect that the user has scrolled to the end of the RecyclerView, we need to implement OnScrollListener() on the RecyclerView.

How do you tell the RecyclerView to start at a specific item position?

If onLayoutChildren is called by RecyclerView, it checks if adapters itemCount is already > 0. If true, it calls scrollToPositionWithOffset() . So I can tell immediately what position should be visible, but it will not be told to LayoutManager before position exists in Adapter. Show activity on this post.

What does NotifyDataSetChanged do in RecyclerView?

notifyDataSetChanged. Notify any registered observers that the data set has changed. There are two different classes of data change events, item changes and structural changes.

How to check which items are visible in recyclerview?

You can use recyclerView.getChildAt () to get each visible child, and setting some tag convertview.setTag (index) on these view in adapter code will help you to relate it with adapter data. Show activity on this post. Following Linear / Grid LayoutManager methods can be used to check which items are visible

Can I animate a recyclerview before the view is visible?

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. Thus, I need a callback method to surely know that a particular view item is visible to the user.

Is there a callback method for a recyclerview item view?

The only known callback method for implementing the logic for each item view of a RecyclerView is 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.

How to get clicked item and its position in recyclerview?

This example demonstrate about how to get clicked item and its position in RecyclerView. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main.xml.


1 Answers

Sorry for answer on Kotlin, I can't check it quickly on Java now. 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.

like image 79
BArtWell Avatar answered Sep 25 '22 14:09

BArtWell