RecyclerViewに現在表示されている要素を知る必要があります。OnScrollListener.onScroll(...)
ListViews のメソッドに相当するものはありません。私はで作業しようとしましたがView.getGlobalVisibleRect(...)
、そのハックはあまりに醜く、いつもうまくいくとは限りません。
誰かアイデアは?
RecyclerViewに現在表示されている要素を知る必要があります。OnScrollListener.onScroll(...)
ListViews のメソッドに相当するものはありません。私はで作業しようとしましたがView.getGlobalVisibleRect(...)
、そのハックはあまりに醜く、いつもうまくいくとは限りません。
誰かアイデアは?
回答:
最初/最後に表示される子はに依存しますLayoutManager
。LinearLayoutManager
またはを使用している場合はGridLayoutManager
、
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
例えば:
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
の場合LinearLayoutManager
、最初/最後はアダプターの注文によって異なります。から子を照会しないでくださいRecyclerView
。LayoutManager
キャッシュ用に表示されるよりも多くのアイテムをレイアウトすることを好むかもしれません。
getItemCount
findFirstVisibleItemPosition
同じ呼び出しで1と-1を返すことができます。
最後に、アダプターのonBindViewHolderイベントから、現在のアイテムが表示されているかどうかを確認するソリューションを見つけました。
重要なのは、LayoutManager のメソッドisViewPartiallyVisibleです。
アダプターでは、RecyclerViewからLayoutManagerを取得できます。これは、onAttachedToRecyclerViewイベントからパラメーターとして取得します。
RecyclerViewアダプター内に実装されるロジックを持っている人は、@ ernestoアプローチをon scrollListenerと組み合わせて使用しwhat you want
て、RecyclerViewが参照されるときに取得できます。アダプター内には、次のようなものが含まれます。
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if(manager instanceof LinearLayoutManager && getItemCount() > 0) {
LinearLayoutManager llm = (LinearLayoutManager) manager;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visiblePosition = llm.findFirstCompletelyVisibleItemPosition();
if(visiblePosition > -1) {
View v = llm.findViewByPosition(visiblePosition);
//do something
v.setBackgroundColor(Color.parseColor("#777777"));
}
}
});
}
}
を使用recyclerView.getChildAt()
して、表示されている各子を取得できます。convertview.setTag(index)
アダプタコードでこれらのビューにタグを設定すると、アダプタデータと関連付けることができます。
recyclerView.getChildAt()
、thatsのは、どのように一般的にRecyclerView
動作します。RecyclerView
現在表示されているいくつかの子ビューのみを保持しようとし(つまり、画面の境界内で、Visibility as GONE、INVISIBLEではありません)、ユーザーがスクロールしたときにこれらのビューをリサイクルしようとします。
補遺:
提案された関数findLast ... Position()は、ツールバーが展開されているときに、ツールバーが折りたたまれているシナリオでは正しく機能しません。
リサイクラービューの高さが固定されているようです。ツールバーが展開されている間、リサイクラーは下に移動し、画面の一部から外れます。結果として、提案された関数の結果は高すぎます。例:最後に表示されるアイテムは#9と表示されますが、実際にはアイテム#7が画面に表示される最後のアイテムです。
この動作は、ビューが正しい位置にスクロールできないことが多かった理由でもあります。つまり、scrollToPosition()が正しく機能しませんでした(最後にプログラムでツールバーを折りたたみました)。
次のLinear / Grid LayoutManager
メソッドを使用して、どのアイテムがvisible
int findFirstVisibleItemPosition();
int findLastVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
is item visible on screen
しきい値を追跡したい場合は、次のブログを参照してください。
https://proandroiddev.com/detecting-list-items-perceived-by-user-8f164dfb1d05
以下の場合はStaggeredGridLayoutManager
次の操作を行います。
RecyclerView rv = findViewById(...);
StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(...);
rv.setLayoutManager(lm);
そして目に見えるアイテムビューを取得するには:
int[] viewsIds = lm.findFirstCompletelyVisibleItemPositions(null);
ViewHolder firstViewHolder = rvPlantios.findViewHolderForLayoutPosition(viewsIds[0]);
View itemView = viewHolder.itemView;
空であることを確認してください。
viewsIds
は配列であり、空の場合があります。