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.
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.
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);
}
}
});
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!
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.
In order to detect that the user has scrolled to the end of the RecyclerView, we need to implement OnScrollListener() on the RecyclerView.
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.
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.
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
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.
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.
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.
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.
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