Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView: find last visible item immediately after view created

I'm having a problem with the following methods:

int firstVisibleItemPosition = gridLayoutManager.findFirstVisibleItemPosition();
int lastVisibleItemPosition = gridLayoutManager.findLastVisibleItemPosition();

My goal: save analytic data about what items the user have viewed.

In order to do that, I'm calling this methods in two different scenarios:

  • every time scrolling turned to "idle" state, and checking what are the visible items. in that case I'm getting the expected indexes.

  • when the RecyclerView become "visible" to the user. now that's when the problem starts. I would expect that when the fragment containing the recylcerView is passed onResume() then calling findLastVisibleItemPosition() will return the visible items. but it return -1, in that case. I guess it have something to do with the asynchronous loading of the recyclerView + adapter internal items initialization relative to the fragment/activity lifecycle.

by postpone this code by a few milliseconds - findLastVisibleItemPosition() returns the right indexes. but I don't want to postpone hard coded using handler + delayed runnable, because scheduling delayed runnable is a work-around to what I really want to do: detect when the recycler view finished inflating and drawing to the screen all the views that can feet inside of it..

so my questions are basically:

  • how can I detect when the RecyclerView finished all the initialzation/measuring/inflating and drawing of it child items that feet into screen? (before any user interaction..).

  • is there any reliable good practice way to know exactly what items within' the recycler view is really shown on screen?

like image 575
Tal Kanel Avatar asked Jul 10 '15 05:07

Tal Kanel


People also ask

How to get current visible item in RecyclerView android?

GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView. getLayoutManager()); int firstVisiblePosition = layoutManager. findFirstVisibleItemPosition();

How can I check if a RecyclerView item is visible?

You could make some logic using LayoutManager api to get last completely visible item position in RecyclerView onScrolled method: ((LinearLayoutManager) vYourRecycler. getLayoutManager()). findLastCompletelyVisibleItemPosition();

What is itemview in RecyclerView?

A RecyclerView. ViewHolder class which caches views associated with the default Preference layouts. A ViewHolder describes an item view and metadata about its place within the RecyclerView. RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View.

When to use Recycler view?

RecyclerView is powerful when you need to customize your list or you want better animations. Those convenience methods in ListView caused a lot of trouble to people which is why RecyclerView provides a more flexible solution to them. The major change you need to make for migration is in your adapter.


Video Answer


1 Answers

What about configuration changes? If the user changes the screen orientation, the visible items will change too. The fact is, visible items are changing constantly according to the state of the RecyclerView, the loaded data, the scroll position and the current screen configuration.

The best thing you can probably do is creating a class which constantly keeps track of the superset of visible items, by making it implement the ItemDecoration interface which is called each time a RecyclerView gets redrawn on screen, and have this component send stats periodically. You would reattach it to the new RecyclerView instance on configuration change (preserving its state).

So for example this component could keep track of the minimum and maximum visible positions. At first it will be -1 for both. Then after the data is loaded and the first items are shown on screen, the ItemDecoration will be called again and first visible item position will now be 0 and last visible item position will now be N. After scroll, the values will change again. You would only keep the min value of FirstVisibleItemPosition and the max value of LastVisibleItemPosition in order to get the superset. After X seconds without changes, or if the user navigates back from the Activity, you would record and send these numbers.

like image 107
BladeCoder Avatar answered Jan 01 '23 21:01

BladeCoder