I'm working with recyclerview with snaphelper. this is my recyclerview:
final LinearLayoutManager lm = new LinearLayoutManager(getContext(),
LinearLayoutManager.HORIZONTAL, false);
recyclerview.setLayoutManager(lm);
final PagerSnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerview);
when user scroll to another cell i need to do something with the new cell position.
this is what i do to get the position:
recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState != RecyclerView.SCROLL_STATE_IDLE) {
return;
}
if recyclerview == null) {
return;
}
//recyclerview.clearOnChildAttachStateChangeListeners();
int firstVisible = ((LinearLayoutManager) viewerRv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
if (firstVisible == RecyclerView.NO_POSITION) {
return;
}
doSomething(firstVisible);
}
the problem is the firstVisible var not always give me the right position for example when i scroll from position 0 to 9 this can be the output: 0,1,2,3,4,4,5,9
there is another way to get the right current position?
what are the best practices for that?
this my solution :
recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
final int offset = topRv.computeHorizontalScrollOffset();
if (offset % myCellWidth == 0) {
final int position = offset / myCellWidth ;
}
}
});
this solution gives me the current position constantly
The documentation for onScrollStateChanged(int state) explain:
SCROLL_STATE_IDLE: No scrolling is done.
SCROLL_STATE_DRAGGING: The user is dragging his finger on the screen (or it is being done programatically.
SCROLL_STATE_SETTLING: User has lifted his finger, and the animation is now slowing down.
You get position when state is SCROLL_STATE_DRAGGING or SCROLL_STATE_SETTLING, obviously this return all of positions that recycler view has scrolled. If you want to get the current position, you should get when the recyclerview stops (newState = SCROLL_STATE_IDLE)
You could use code similar to this for control start and ends of scroll:
boolean hasStarted = (state == SCROLL_STATE_DRAGGING);
boolean hasEnded = (state == SCROLL_STATE_IDLE);
So the final code could be some like this:
//Initialize this variable on class that initialize recyclerview
private boolean hasStarted;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//Scroll is not start and user is dragging his finger
if(!hasStarted && newState == SCROLL_STATE_DRAGGING){
hasStarted = true;
}
//If scroll starts and it finish
if(hasStarted && newState == SCROLL_STATE_IDLE){
//Restart variable for next iteration
hasStarted = false;
//Do something
doSomething(firstVisible);
}
}
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