Android의 RecyclerView은 대용량의 데이터를 효율적으로 보여주는 뷰입니다. 하지만 그렇다고 대용량의 데이터를 한 번에 보여주는 것은 비효율적입니다. 적당한 크기의 데이터로 보여주고 필요에 따라서 데이터를 점차 추가하는 형태로 구현하는 것이 좋습니다. RecyclerView Pagination 패턴이라고 할까요
이때 중요한 부분은 데이터를 추가로 Fetch 하는 시점을 잡는 것입니다. 보통 RecyclerView의 스크롤의 끝에 도달했을 때입니다.
Android Jetpack Paging 라이브러리는 개발자가 쉽게 Pagination 패턴을 구현하는 방법을 제공해 줍니다. 데이터를 적절한 시점에 Fetch 하는 것뿐만 아니라 캐시, 에러 처리 등 유용한 기능들이 많이 포함되어 있습니다. 그래서 RecyclerView로 Pagination을 구현하신다면 Paging 라이브러리를 먼저 사용해 보는 것을 추천합니다.
canScrollVertically, canScrollHorizontally
canScrollVertically, canScrollHorizontally 함수는 방향만 다를 뿐 내부 동작은 다르지 않습니다. 그래서 편의상 canScrollVertically 함수를 주로 다루려고 합니다.
/**
* Check if this view can be scrolled vertically in a certain direction.
*
* <p>This is without regard to whether the view is enabled or not, or if it will scroll
* in response to user input or not.
*
* @param direction Negative to check scrolling up, positive to check scrolling down.
* @return true if this view can be scrolled in the specified direction, false otherwise.
*/
public boolean canScrollVertically(int direction) {
final int offset = computeVerticalScrollOffset();
final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
if (range == 0) return false;
if (direction < 0) {
return offset > 0;
} else {
return offset < range - 1;
}
}
canScrollVerifcally 함수는 View에 정의된 함수입니다. 코드를 조금 살펴보면
computeVerticalScrollOffset 함수는 초기 위치에서 스크롤된 위치까지의 차이를 의미하는 offset 정수형 값을 반환합니다.
그리고 스크롤 가능한 range, 범위를 계산해 스크롤이 가능한지 판단합니다.
View는 일반적으로 스크롤 가능하지 않습니다. 그래서 computeVerticalScrollRange, computeVerticalScrollExtent 함수의 값은 동일하게 View의 높이를 반환합니다. 따라서 range 값이 항상 0이 됩니다.
만약 range가 값이 0이 아니라면, direction에 따라서 스크롤 가능한지 계산하게 됩니다.
// RecyclerView
@Override
public int computeVerticalScrollRange() {
if (mLayout == null) {
return 0;
}
return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollRange(mState) : 0;
}
// RecyclerView
@Override
public int computeVerticalScrollExtent() {
if (mLayout == null) {
return 0;
}
return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollExtent(mState) : 0;
}
RecyclerView는 위 두 함수를 재정의해서 스크롤 range의 값이 반환됩니다. 참고로 mLayout은 RecyclerView에서 실제 뷰를 배치하고 관리하는 LayoutManager입니다.
간단한 사용 방법
rv.canScrollVertically(1) // 아래로 스크롤이 가능한지
rv.canScrollVertically(-1) // 위로 스크롤이 가능한지
rv.canScrollHorizontally(1) //오른쪽으로 스크롤이 가능한지
rv.canScrollHorizontally(-1) //왼쪽으로 스크롤이 가능한지
정리하자면 recyclerView 객체에 canScrollVertically 함수의 매개변수로 1을 주면 아래로 스크롤 가능한지 판단합니다.
-1 인자는 반대로 위로 스크롤 가능한지 판단합니다.
함수의 값이 false가 나온다면 스크롤의 끝에 다다랐다는 뜻입니다.
구현
rv.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (!rv.canScrollVertically(-1)) {
Log.i(TAG, "Top of list");
} else if (!rv.canScrollVertically(1)) {
Log.i(TAG, "End of list");
} else {
Log.i(TAG, "idle");
}
}
});
이제 이 함수를 호출하는 시점만 잡으면 됩니다. 결론만 말하자면 스크롤이 변화되는 시점마다 체크해야 실시간으로 확인할 수 있을 것입니다.
따라서 setOnScrollListener 함수로 스크롤 리스너를 등록해서 매번 체크해 주면 됩니다.
'Android > Common' 카테고리의 다른 글
[Android] 음성 인식 기능 추가하는 방법 정리 (0) | 2020.03.26 |
---|---|
[Android] AAC - View Binding (0) | 2020.03.12 |
[Android] 면접에서 헷갈릴수 있는 Activity Lifecycle (0) | 2020.03.05 |
[Android] Retrofit 라이브러리 알아보기 (0) | 2020.02.09 |
[Android] Settings.Panel (0) | 2019.12.13 |
Android의 RecyclerView은 대용량의 데이터를 효율적으로 보여주는 뷰입니다. 하지만 그렇다고 대용량의 데이터를 한 번에 보여주는 것은 비효율적입니다. 적당한 크기의 데이터로 보여주고 필요에 따라서 데이터를 점차 추가하는 형태로 구현하는 것이 좋습니다. RecyclerView Pagination 패턴이라고 할까요
이때 중요한 부분은 데이터를 추가로 Fetch 하는 시점을 잡는 것입니다. 보통 RecyclerView의 스크롤의 끝에 도달했을 때입니다.
Android Jetpack Paging 라이브러리는 개발자가 쉽게 Pagination 패턴을 구현하는 방법을 제공해 줍니다. 데이터를 적절한 시점에 Fetch 하는 것뿐만 아니라 캐시, 에러 처리 등 유용한 기능들이 많이 포함되어 있습니다. 그래서 RecyclerView로 Pagination을 구현하신다면 Paging 라이브러리를 먼저 사용해 보는 것을 추천합니다.
canScrollVertically, canScrollHorizontally
canScrollVertically, canScrollHorizontally 함수는 방향만 다를 뿐 내부 동작은 다르지 않습니다. 그래서 편의상 canScrollVertically 함수를 주로 다루려고 합니다.
/**
* Check if this view can be scrolled vertically in a certain direction.
*
* <p>This is without regard to whether the view is enabled or not, or if it will scroll
* in response to user input or not.
*
* @param direction Negative to check scrolling up, positive to check scrolling down.
* @return true if this view can be scrolled in the specified direction, false otherwise.
*/
public boolean canScrollVertically(int direction) {
final int offset = computeVerticalScrollOffset();
final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
if (range == 0) return false;
if (direction < 0) {
return offset > 0;
} else {
return offset < range - 1;
}
}
canScrollVerifcally 함수는 View에 정의된 함수입니다. 코드를 조금 살펴보면
computeVerticalScrollOffset 함수는 초기 위치에서 스크롤된 위치까지의 차이를 의미하는 offset 정수형 값을 반환합니다.
그리고 스크롤 가능한 range, 범위를 계산해 스크롤이 가능한지 판단합니다.
View는 일반적으로 스크롤 가능하지 않습니다. 그래서 computeVerticalScrollRange, computeVerticalScrollExtent 함수의 값은 동일하게 View의 높이를 반환합니다. 따라서 range 값이 항상 0이 됩니다.
만약 range가 값이 0이 아니라면, direction에 따라서 스크롤 가능한지 계산하게 됩니다.
// RecyclerView
@Override
public int computeVerticalScrollRange() {
if (mLayout == null) {
return 0;
}
return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollRange(mState) : 0;
}
// RecyclerView
@Override
public int computeVerticalScrollExtent() {
if (mLayout == null) {
return 0;
}
return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollExtent(mState) : 0;
}
RecyclerView는 위 두 함수를 재정의해서 스크롤 range의 값이 반환됩니다. 참고로 mLayout은 RecyclerView에서 실제 뷰를 배치하고 관리하는 LayoutManager입니다.
간단한 사용 방법
rv.canScrollVertically(1) // 아래로 스크롤이 가능한지
rv.canScrollVertically(-1) // 위로 스크롤이 가능한지
rv.canScrollHorizontally(1) //오른쪽으로 스크롤이 가능한지
rv.canScrollHorizontally(-1) //왼쪽으로 스크롤이 가능한지
정리하자면 recyclerView 객체에 canScrollVertically 함수의 매개변수로 1을 주면 아래로 스크롤 가능한지 판단합니다.
-1 인자는 반대로 위로 스크롤 가능한지 판단합니다.
함수의 값이 false가 나온다면 스크롤의 끝에 다다랐다는 뜻입니다.
구현
rv.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (!rv.canScrollVertically(-1)) {
Log.i(TAG, "Top of list");
} else if (!rv.canScrollVertically(1)) {
Log.i(TAG, "End of list");
} else {
Log.i(TAG, "idle");
}
}
});
이제 이 함수를 호출하는 시점만 잡으면 됩니다. 결론만 말하자면 스크롤이 변화되는 시점마다 체크해야 실시간으로 확인할 수 있을 것입니다.
따라서 setOnScrollListener 함수로 스크롤 리스너를 등록해서 매번 체크해 주면 됩니다.
'Android > Common' 카테고리의 다른 글
[Android] 음성 인식 기능 추가하는 방법 정리 (0) | 2020.03.26 |
---|---|
[Android] AAC - View Binding (0) | 2020.03.12 |
[Android] 면접에서 헷갈릴수 있는 Activity Lifecycle (0) | 2020.03.05 |
[Android] Retrofit 라이브러리 알아보기 (0) | 2020.02.09 |
[Android] Settings.Panel (0) | 2019.12.13 |