Google Playアプリの水平リストのように、スクロール後にアイテムを中央にスナップする水平RecyclerView
を実装しています。 This はレビューです。
私のコードは以下の通りです:
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
が中央にスナップした後、中央のアイテム(位置)を取得するにはどうすればよいですか?このためのリスナーの実装はありませんか?また、アイテムビューをタッチしたときに中央にスナップしたい。これどうやってするの?
ビューが必要な場合は、
View view = snapHelper.findSnapView(layoutManagaer);
ビューを取得すると、そのビューのデータセット上の位置を取得できるようになります。たとえば、
mainMenu.getChildAdapterPosition(view)
この方法を使用する方が良い:
https://medium.com/over-engineering/detecting-snap-changes-with-androids-recyclerview-snaphelper-9e9f5e95c424
元の投稿: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
を選択した場合、コールバックオブジェクトは中央の要素位置を返します。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);
}
}