일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Error:Execution failed for task ':app:mergeDebugResources'
- Android
- 안드로이드개발레벨업교과서
- binding adapter
- 뷰변경 감지
- 재사용
- fragment
- 안드로이드13
- LayoutManger
- 리사이클러뷰
- 스와이프
- Fragment 수동 추가
- 안드로이드스튜디오
- recyclerview
- ui test
- searchview
- 코딜리티
- 안드로이드
- adapter
- espresso
- 테마 아이콘
- 코틀린
- 생명주기
- ActivityTestRule
- 고차함수
- high order function
- viewholder
- 구분선
- IntentTestRule
- Fragment에서 Activity의 함수 사용하기
Archives
- Today
- Total
룬아님의 취중코딩
Recyclerview의 보여지는 뷰의 index 변화를 알려주는 Listener 본문
리사이클러뷰를 사용하면서 특정 위치의 뷰가 보여지는 시점이라던지 더이상 보이지 않게 되는 시점에 해당 뷰의 위치를 가져와야 하는 경우가 종종있습니다. 저의 경우에는 각 뷰의 노출 횟수를 집계하기 위하여 이 리스너를 직접 구현하여 사용하였습니다.
https://github.com/myung6024/VisiblePositionChangeListener
보여지는 View와 가려지는 View의 position을 감지하는 Linstener
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
public class VisiblePositionChangeListener extends RecyclerView.OnScrollListener {
public interface OnChangeListener {
void onFirstVisiblePositionChanged(int position);
void onLastVisiblePositionChanged(int position);
void onFirstInvisiblePositionChanged(int position);
void onLastInvisiblePositionChanged(int position);
}
private int firstVisiblePosition;
private int lastVisiblePosition;
private final OnChangeListener listener;
private LinearLayoutManager layoutManager;
public VisiblePositionChangeListener(LinearLayoutManager linearLayoutManager, OnChangeListener listener) {
this.listener = listener;
this.firstVisiblePosition = RecyclerView.NO_POSITION;
this.lastVisiblePosition = RecyclerView.NO_POSITION;
this.layoutManager = linearLayoutManager;
}
public VisiblePositionChangeListener(LinearLayoutManager linearLayoutManager, OnChangeListener listener) {
this.listener = listener;
this.firstVisiblePosition = RecyclerView.NO_POSITION;
this.lastVisiblePosition = RecyclerView.NO_POSITION;
this.layoutManager = linearLayoutManager;
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstPosition = layoutManager.findFirstVisibleItemPosition();
int lastPosition = layoutManager.findLastVisibleItemPosition();
if (firstVisiblePosition == RecyclerView.NO_POSITION || lastVisiblePosition == RecyclerView.NO_POSITION) {
firstVisiblePosition = firstPosition;
lastVisiblePosition = lastPosition;
return;
}
if (firstPosition < firstVisiblePosition) {
if (firstVisiblePosition - firstPosition > 1) {
for (int i = 1; i < firstVisiblePosition - firstPosition + 1; i++) {
listener.onFirstVisiblePositionChanged(firstVisiblePosition - i);
}
} else {
listener.onFirstVisiblePositionChanged(firstPosition);
}
firstVisiblePosition = firstPosition;
} else if (firstPosition > firstVisiblePosition) {
if (firstPosition - firstVisiblePosition > 1) {
for (int i = firstPosition - firstVisiblePosition; i > 0; i--) {
listener.onFirstInvisiblePositionChanged(firstPosition - i);
}
} else {
listener.onFirstInvisiblePositionChanged(firstVisiblePosition);
}
firstVisiblePosition = firstPosition;
}
if (lastPosition > lastVisiblePosition) {
if (lastPosition - lastVisiblePosition > 1) {
for (int i = 1; i < lastPosition - lastVisiblePosition + 1; i++) {
listener.onLastVisiblePositionChanged(lastVisiblePosition + i);
}
} else {
listener.onLastVisiblePositionChanged(lastPosition);
}
lastVisiblePosition = lastPosition;
} else if (lastPosition < lastVisiblePosition) {
if (lastVisiblePosition - lastPosition > 1) {
for (int i = 0; i < lastVisiblePosition - lastPosition; i++) {
listener.onLastInvisiblePositionChanged(lastVisiblePosition - i);
}
} else {
listener.onLastInvisiblePositionChanged(lastVisiblePosition);
}
lastVisiblePosition = lastPosition;
}
}
}
보여지는 View의 position을 감지하는 Linstener
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
public class VisiblePositionChangeListener extends RecyclerView.OnScrollListener {
public interface OnChangeListener {
void onFirstVisiblePositionChanged(int position);
void onLastVisiblePositionChanged(int position);
}
private int firstVisiblePosition;
private int lastVisiblePosition;
private final OnChangeListener listener;
private LinearLayoutManager layoutManager;
public VisiblePositionChangeListener(LinearLayoutManager linearLayoutManager, OnChangeListener listener) {
this.listener = listener;
this.firstVisiblePosition = RecyclerView.NO_POSITION;
this.lastVisiblePosition = RecyclerView.NO_POSITION;
this.layoutManager = linearLayoutManager;
}
public VisiblePositionChangeListener(LinearLayoutManager linearLayoutManager, OnChangeListener listener) {
this.listener = listener;
this.firstVisiblePosition = RecyclerView.NO_POSITION;
this.lastVisiblePosition = RecyclerView.NO_POSITION;
this.layoutManager = linearLayoutManager;
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstPosition = layoutManager.findFirstVisibleItemPosition();
int lastPosition = layoutManager.findLastVisibleItemPosition();
if (firstVisiblePosition == RecyclerView.NO_POSITION || lastVisiblePosition == RecyclerView.NO_POSITION) {
firstVisiblePosition = firstPosition;
lastVisiblePosition = lastPosition;
return;
}
if (firstPosition < firstVisiblePosition) {
if (firstVisiblePosition - firstPosition > 1) {
for (int i = 1; i < firstVisiblePosition - firstPosition + 1; i++) {
listener.onFirstVisiblePositionChanged(firstVisiblePosition - i);
}
} else {
listener.onFirstVisiblePositionChanged(firstPosition);
}
firstVisiblePosition = firstPosition;
} else if (firstPosition > firstVisiblePosition) {
firstVisiblePosition = firstPosition;
}
if (lastPosition > lastVisiblePosition) {
if (lastPosition - lastVisiblePosition > 1) {
for (int i = 1; i < lastPosition - lastVisiblePosition + 1; i++) {
listener.onLastVisiblePositionChanged(lastVisiblePosition + i);
}
} else {
listener.onLastVisiblePositionChanged(lastPosition);
}
lastVisiblePosition = lastPosition;
} else if (lastPosition < lastVisiblePosition) {
lastVisiblePosition = lastPosition;
}
}
}
사용법
recyclerView.addOnScrollListener(new VisiblePositionChangeListener(layoutManager,
new VisiblePositionChangeListener.OnChangeListener() {
@Override
public void onFirstVisiblePositionChanged(int position) {
//첫번째 보이는 아이템이 변경되었을 때
//보이게 된 아이템의 position을 리턴
}
@Override
public void onLastVisiblePositionChanged(int position) {
//마지막 보이는 아이템이 변경되었을 때
//보이게 된 아이템의 position을 리턴
}
}
));
recyclerView.addOnScrollListener(new VisiblePositionChangeListener(layoutManager,
new VisiblePositionChangeListener.OnChangeListener() {
@Override
public void onFirstVisiblePositionChanged(int position) {
//첫번째 보이는 아이템이 변경되었을 때
//보이게 된 아이템의 position을 리턴
}
@Override
public void onLastVisiblePositionChanged(int position) {
//마지막 보이는 아이템이 변경되었을 때
//보이게 된 아이템의 position을 리턴
}
@Override
public void onFirstInvisiblePositionChanged(int position) {
//첫번째 안보이는 아이템이 변경되었을 때
//안보이게 된 아이템의 position을 리턴
}
@Override
public void onLastInvisiblePositionChanged(int position) {
//마지막 안보이는 아이템이 변경되었을 때
//안보이게 된 아이템의 position을 리턴
}
}
));
리스너에는 보여지는 뷰 위치만 리턴하는 리스너와 가려지는 뷰 위치도 리턴하는 리스너가 따로 구현되어 있습니다. 두 개의 리스너 중 필요한 리스너를 택하여 사용하면 됩니다.
반응형
'개발 > 안드로이드 개발' 카테고리의 다른 글
Error:Execution failed for task ':app:mergeDebugResources'. (0) | 2019.08.20 |
---|---|
Koin으로 Dialog 사용하기 (0) | 2019.08.17 |
Android RecyclerView 어댑터에서 필터 후 원래 항목 위치를 얻는 방법 (0) | 2019.08.05 |
다이얼로그에 왜 application context를 사용하면 안될까? (1) | 2019.08.05 |
안드로이드 버튼 리플 효과 적용 (0) | 2019.08.05 |
Comments