Как получить центральный элемент после того, как RecyclerView привязал его к центру?
Я реализую горизонтальный RecyclerView
которые привязывают элементы к центру после прокрутки, как горизонтальные списки Google Play App. Это обзор.
Мой код ниже:
MainMenuAdapter mainMenuAdapter = new MainMenuAdapter(this, mDataset);
final LinearLayoutManager layoutManagaer = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView mainMenu = (RecyclerView) findViewById(R.id.main_menu);
mainMenu.setLayoutManager(layoutManagaer);
mainMenu.setAdapter(mainMenuAdapter);
final SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(mainMenu);
Как я могу получить центральный пункт (позицию) после RecyclerView
щелкнул по центру? Нет ли реализации для этого слушателя? Также при касании вида элемента я хочу привязать его к центру. Как я могу это сделать?
2 ответа
Если вам нужен вид, вы можете позвонить
View view = snapHelper.findSnapView(layoutManagaer);
как только у вас появится представление, вы сможете получить позицию в наборе данных для этого представления. Например, используя
mainMenu.getChildAdapterPosition(view)
Даже если вы не собираетесь использовать SnapHelper
Вы можете получить положение центрального элемента, RecyclerView.OnScrollListener
,
- копия
MiddleItemFinder
класс для вашего проекта. Создать объект обратного вызова
MiddleItemCallback
,MiddleItemFinder.MiddleItemCallback callback = new MiddleItemFinder.MiddleItemCallback() { @Override public void scrollFinished(int middleElement) { // interaction with middle item } };
Добавить новый слушатель прокрутки к вашему
RecyclerView
recyclerView.addOnScrollListener( new MiddleItemFinder(getContext(), layoutManager, callback, RecyclerView.SCROLL_STATE_IDLE));
Последний параметр или
MiddleItemFinder
конструкторscrollState
,RecyclerView.SCROLL_STATE_IDLE
- RecyclerView в настоящее время не прокручивается. Прокрутка закончена.RecyclerView.SCROLL_STATE_DRAGGING
- RecyclerView в настоящее время перетаскивается с помощью внешнего ввода, такого как сенсорный ввод пользователя.RecyclerView.SCROLL_STATE_SETTLING
- RecyclerView в настоящее время анимируется до конечной позиции, не находясь под внешним контролем.MiddleItemFinder.ALL_STATES
- Все штаты вместе.
- Например, если вы выберете
RecyclerView.SCROLL_STATE_IDLE
в качестве последнего параметра конструктора, чем в конце всей прокрутки, объект обратного вызова вернет вам среднюю позицию элемента.
Класс MiddleItemFinder:
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);
}
}