현재 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()
일반적인 항목 만 표시되는 항목 만 표시됩니다 RecyclerView
. RecyclerView
는 현재 표시되는 하위 뷰를 몇 개만 유지하려고합니다 (예 : 화면 경계 내에서 가시성으로 보이지 않음). 사용자 스크롤시 이러한 뷰를 재활용하려고합니다.
다음 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 () 이 제대로 작동 하지 않습니다 .
리사이클 러보기의 높이는 고정되어 있으며 도구 모음이 확장 된 상태에서 리사이클 러는 화면 밖으로 부분적으로 이동합니다. 결과적으로 제안 된 기능의 결과가 너무 높습니다. 예 : 마지막으로 보이는 항목은 # 9라고하지만 실제로 항목 # 7은 화면에있는 마지막 항목입니다.
이 동작은 또한 내보기가 종종 올바른 위치로 스크롤하는 데 실패한 이유입니다.
이를 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
배열이며 비어있을 수 있습니다.