How to get the center item after RecyclerView snapped it to center?
if you need the View, you can call
View view = snapHelper.findSnapView(layoutManagaer);
once you have the View, you should be able to get the position on the dataset for that View. For instance using
mainMenu.getChildAdapterPosition(view)
Better to use this method:
https://medium.com/over-engineering/detecting-snap-changes-with-androids-recyclerview-snaphelper-9e9f5e95c424
Original post:
Even if you are not going to use SnapHelper
you can get the central element position by RecyclerView.OnScrollListener
.
- Copy
MiddleItemFinder
class to your project. Create callback object
MiddleItemCallback
.MiddleItemFinder.MiddleItemCallback callback = new MiddleItemFinder.MiddleItemCallback() { @Override public void scrollFinished(int middleElement) { // interaction with middle item } };
Add new scroll listener to your
RecyclerView
recyclerView.addOnScrollListener( new MiddleItemFinder(getContext(), layoutManager, callback, RecyclerView.SCROLL_STATE_IDLE));
The last parameter or
MiddleItemFinder
constructor isscrollState
.RecyclerView.SCROLL_STATE_IDLE
– The RecyclerView is not currently scrolling. Scroll finished.RecyclerView.SCROLL_STATE_DRAGGING
– The RecyclerView is currently being dragged by outside input such as user touch input.RecyclerView.SCROLL_STATE_SETTLING
– The RecyclerView is currently animating to a final position while not under outside control.MiddleItemFinder.ALL_STATES
– All states together.
- For example, if you choose
RecyclerView.SCROLL_STATE_IDLE
as the last constructor parameter than in the end of all scroll the callback object will return you the middle element position.
MiddleItemFinder class:
public class MiddleItemFinder extends RecyclerView.OnScrollListener {
private
Context context;
private
LinearLayoutManager layoutManager;
private
MiddleItemCallback callback;
private
int controlState;
public
static final int ALL_STATES = 10;
public MiddleItemFinder(Context context, LinearLayoutManager layoutManager, MiddleItemCallback callback, int controlState) {
this.context = context;
this.layoutManager = layoutManager;
this.callback = callback;
this.controlState = controlState;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (controlState == ALL_STATES || newState == controlState) {
int firstVisible = layoutManager.findFirstVisibleItemPosition();
int lastVisible = layoutManager.findLastVisibleItemPosition();
int itemsCount = lastVisible - firstVisible + 1;
int screenCenter = context.getResources().getDisplayMetrics().widthPixels / 2;
int minCenterOffset = Integer.MAX_VALUE;
int middleItemIndex = 0;
for (int index = 0; index < itemsCount; index++) {
View listItem = layoutManager.getChildAt(index);
if (listItem == null)
return;
int leftOffset = listItem.getLeft();
int rightOffset = listItem.getRight();
int centerOffset = Math.abs(leftOffset - screenCenter) + Math.abs(rightOffset - screenCenter);
if (minCenterOffset > centerOffset) {
minCenterOffset = centerOffset;
middleItemIndex = index + firstVisible;
}
}
callback.scrollFinished(middleItemIndex);
}
}
public interface MiddleItemCallback {
void scrollFinished(int middleElement);
}
}