RecyclerViewにどの要素が現在表示されているかを知る必要があります。 ListViewsの OnScrollListener.onScroll(...)
メソッドに相当するものはありません。私は View.getGlobalVisibleRect(...)
で作業しようとしましたが、そのハックは醜すぎていつもうまくいくとは限らない。
誰かアイデアがありますか?
最初/最後に見える子はLayoutManager
に依存します。 LinearLayoutManager
またはGridLayoutManager
を使用している場合は、次のように使用できます。
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
例えば:
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
LinearLayoutManager
の場合、first/lastはアダプタの順序によって異なります。 RecyclerView
から子供たちに問い合わせてはいけません。 LayoutManager
はキャッシングのために見えるよりも多くの項目をレイアウトすることを好むかもしれません。
最後に、アダプタのonBindViewHolderイベントから、現在の項目が表示されているかどうかを確認するための解決策を見つけました。
重要なのは、LayoutManagerのメソッドisViewPartiallyVisibleです。
アダプタでは、RecyclerViewからLayoutManagerを取得できます。これは、 onAttachedToRecyclerView イベントのパラメータとして取得します。
表示可能な各子を取得するにはrecyclerView.getChildAt()
を使用できます。アダプタコードでこれらのビューにタグconvertview.setTag(index)
を設定すると、アダプタデータと関連付けるのに役立ちます。
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;
空かどうかを確認してください。
以下の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
補遺 :
提案された関数 findLast ... Position() do not は、ツールバーが展開されているときに折りたたみ式ツールバーがあるシナリオでは正しく機能します。
リサイクラビューの高さは固定されているようで、ツールバーが展開されている間は、リサイクラが下に移動し、画面の一部が見えなくなります。結果として、提案された機能の結果は高すぎる。例:最後の目に見えるアイテムは#9であると言われます、しかし実際にはアイテム#7はスクリーン上にある最後のアイテムです。
この動作が、ビューが正しい位置にスクロールできなかった、つまりscrollToPosition()が正しく機能しなかった(プログラムによってツールバーを最後に折りたたんだ)理由でもあります。
recyclerViewアダプタの内部に実装するロジックを持っている人のために、RecyclerViewが調べられるのでwhat you want
を取得するためにon scrollListenerと組み合わせて@ernestoアプローチをまだ使うことができます。アダプタの中には、次のようなものがあります。
@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"));
}
}
});
}
}