RecyclerView rv = findViewById(...); StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(...); rv. setLayoutManager(lm); And to get visible item views: int[] viewsIds = lm.
You can retrieve count by using the ArrayList's size() method. So, in your case you can calculate using episodeList. size() . For setting the list size to TextView in Activity.
You can use Scroll listener to detect scroll up or down changes in RecyclerView . RecycleView invokes the onScrollStateChanged() method before onScrolled() method. The onScrollStateChanged() method provides you the RecycleView's status: SCROLL_STATE_IDLE : No scrolling.
First / last visible child depends on the LayoutManager
.
If you are using LinearLayoutManager
or GridLayoutManager
, you can use
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
For example:
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
For LinearLayoutManager
, first/last depends on the adapter ordering. Don't query children from RecyclerView
; LayoutManager
may prefer to layout more items than visible for caching.
for those who have a logic to be implemented inside the RecyclerView adapter you can still use @ernesto approach combined with an on scrollListener to get what you want
as the RecyclerView is consulted.
Inside the adapter you will have something like this:
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if(manager instanceof LinearLayoutManager && getItemCount() > 0) {
LinearLayoutManager llm = (LinearLayoutManager) manager;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visiblePosition = llm.findFirstCompletelyVisibleItemPosition();
if(visiblePosition > -1) {
View v = llm.findViewByPosition(visiblePosition);
//do something
v.setBackgroundColor(Color.parseColor("#777777"));
}
}
});
}
}
Finally, I found a solution to know if the current item is visible, from the onBindViewHolder event in the adapter.
The key is the method isViewPartiallyVisible from LayoutManager.
In your adapter, you can get the LayoutManager from the RecyclerView, which you get as parameter from the onAttachedToRecyclerView event.
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.
Following Linear / Grid LayoutManager
methods can be used to check which items are visible
int findFirstVisibleItemPosition();
int findLastVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
and if you want to track is item visible on screen
for some threshold then you can refer to the following blog.
https://proandroiddev.com/detecting-list-items-perceived-by-user-8f164dfb1d05
Addendum:
The proposed functions findLast...Position() do not work correctly in a scenario with a collapsing toolbar while the toolbar is expanded.
It seems that the recycler view has a fixed height, and while the toolbar is expanded, the recycler is moved down, partially out of the screen. As a consequence, the results of the proposed functions are too high. Example: The last visible item is told to be #9, but in fact item #7 is the last one that is on screen.
This behavior is also the reason why my view often failed to scroll to the correct position, i.e. scrollToPosition() did not work correctly (I finally collapsed the toolbar programmatically).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With