배경
현재 보고있는 혹은 포커스하고 있는 RecyclerView의 스크롤 상태를 체크해야하는 경우가 존재한다. 이 경우에 어떻게 포커스하는가에 대해 작성하고자 한다
구현 방법
1. 현재 스크롤 상태 체크
addOnScrollListener 사용
관련 공식문서: RecyclerView.OnScrollListener | Android Developers
기존 RecyclerView에 OnScrollListener()를 추가해 onScrolled와 onScrollStateChanged를 override해서 현재 스크롤 상태를 체크할 수 있다.
1. onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int)
→ 스크롤이 되는 중일때 호출
dx, dy 변수는 각자 수직/수평으로 스크롤이 얼마나 되었는지 그 양을 뜻한다.
(스크롤 위치가 아니라는 점을 유의)
→ 현재 위치를 0으로 기준을 잡고, dy < 0
이면 위로 스크롤, dy > 0
이면 아래로 스크롤 한 것
2. onScrollStateChanged(recyclerView: RecyclerView, newState: Int)
→ 스크롤이 끝났을 때 호출
- 기존
onScroll
메소드가 스크롤 할 때마다 호출되어 반응성이 좋게 코드를 만들수도 있지만, 빈번한 호출로 앱이 버벅일 수도 있다. - 해당 메소드는 그러한 점을 고쳐
newState
로 들어오는 스크롤 상태변수는 상태가 변할 때마다, 1번만 호출돼 값을 넘겨준다. - newState(스크롤 상태) 변수는 3개가 존재한다
1. SCROLL_STATE_SETTLING
→ 위든 아래든 스크롤이 끝까지 간 상태
2. SCROLL_STATE_IDLE
→ 현재 스크롤을 하지 않는 상태
3. SCROLL_STATE_DRAGGING
→ 스크롤을 하고 있는 상태
사용 예시
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
// Scrolling up
} else {
// Scrolling down
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
// Do something
} else if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
// Do something
} else {
// Do something
}
}
});
예시 2
onScrolled
와 onScrollStatedChanged
를 결합해 위로 스크롤하고 있는지 아래로 스크롤하고 있는지 또한 구현할 수 있을 것이다.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
private boolean isScrolledDown = false;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_SETTLING && isScrolledDown) {
// Do something...
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
isScrolledDown = dy < 0;
}
});
2. 스크롤과 단순 터치 분기
단순히 현재 사용자가 스크롤을 하고 있는지 멈춘 것인지 여부뿐만 아니라, 사용자가 실행한 동작이 스크롤을 한 것인지 단순히 터치한 것인지에 대한 분기처리가 필요했다.
이 경우엔 ScrollListener
가 아닌, TouchListener
를 사용해야 한다
view.setOnTouchListener(new OnTouchListener() {
private long startClickTime;
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startClickTime = System.currentTimeMillis();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {
// Touch was a simple tap. Do whatever.
} else {
// Touch was a not a simple tap.
}
}
return false;
// true로 설정할 경우 기존 touch 동작이 consumed되므로 스크롤은 되지 않는다.
}
});
유저가 화면을 터치하기 시작하는 시각과 손가락이 떼지는 시각의 차를 계산하여 스크롤 여부를 확인하는 방법이다.
'IT > Android' 카테고리의 다른 글
[Android/FCM] (1) Firebase Cloud Messaging의 기초 개념및 구조 (0) | 2023.02.05 |
---|---|
[Android/Retrofit] Effective Error Handling을 위한 CallAdapter의 활용 (0) | 2023.01.25 |
[Android Env]Keystore 비밀번호를 잊어버렸을 때 (2) | 2023.01.21 |
[Android] Custom App Bar 사용 - Kotlin (0) | 2021.07.27 |
[Android] (2) SharedPreferences의 사용 - Kotlin (2) | 2021.07.26 |