IT/Android

[Android] Recyclerview 에서 마지막 아이템 판단하는 방법(Detect when the RecyclerView reaches the bottom)

토마토조아 2019. 2. 8. 15:12
728x90

최근 안드로이드에서는 리스트뷰(Listview) 대신 리사이클러뷰(Recyclerview)를 사용하는 추세로 흘러가고 있다. 리스트뷰의 단점인 메모리 관리나 리스트 레이아웃의 제한적인 기능을 보완할 수 있기 때문이다. 리사이클러뷰를 사용하면 구글 킵처럼 2개의 열에 다양한 크기의 리스트 아이템을 보여주는 것도 가능하고(staggeredGridLayoutManager) 메모리 관리 면에서도 장점이 있다고 한다.

각설은 여기까지 하고, 리사이클러뷰를 사용하면서 마지막 아이템을 판단하는 부분이 은근 사용할 곳이 많다. 마지막 아이템이 보여지면 그 다음 데이터를 로딩한다거나.. 마지막 아이템이 보여질때 풋터(Footer)를 추가한다거나 하는 등의 작업을 할때 유용하다. 주로 전자의 경우 많이 사용하게 될 것이다.

마지막 아이템인지 판단하는 소스를 바로 보자 정말 간단하고 쉽다.

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

LinearLayoutManager layoutManager = LinearLayoutManager.class.cast(recyclerView.getLayoutManager());
int totalItemCount = layoutManager.getItemCount();
int lastVisible = layoutManager.findLastCompletelyVisibleItemPosition();

if (lastVisible >= totalItemCount - 1) {
Log.d(TAG, "lastVisibled");
}
}
};

위 소스 코드를 보면 리사이클러뷰의 OnScrollListener 를 만들어서 리사이클러뷰에 리스너 등록만 해주면 바로 알 수 있다. 위의 코드에서는 리스트 마지막에 다다르면 lastVisibled 라는 로그를 찍도록 해놨는데, 저 부분에 필요한 동작을 선언하면 여기 저기 활용할 수 있다.

이 코드에서의 핵심은 findLastCompletelyVisibleItemPosition 메서드이다. 얘는 마지막 아이템이 완전히 보일때 해당 Position을 알려준다.

lastVisible >= totalItemCount - 1 부분은 설명을 안해도 알겠지만, lastVisible 은 Position을 반납하기 때문에 0부터 시작이 된다. 그리고 totalItemCount 얘는 리사이클러뷰가 가진 총 아이템 갯수이기 때문에 -1을 하여 Position 기준으로 맞춰주는 것이다. ex) 1개의 아이템을 가지고 있다. Position은 0으로 나올 것이고, totalItemCount 는 1로 나오게 된다. 가릿?

LinearLayoutManager 로 사용한 이유는 위에서 사용한 리사이클러뷰를 리니어레이아웃매니저로 적용해서 그런 것이고, 만약 staggeredGridLayoutManager 같은 것은 사용하였다면 해당 클래스로 바꿔서 사용하면 되겠다.

이 내용으로 구글링을 하면 OnScrollStateChanged 를 사용하라는 것도 있는데, 얘로도 충분히 판단을 할 수 있지만 추천하고 싶지는 않다. 이유는 OnScrollStateChanged 이 마지막을 판단하는 로직은 더이상 스크롤이 불가능 할때를 찾아내서 콜백을 주는데, 그 콜백이 마지막에 다다르면 너무 많이 오게 된다. 한번에 막 3~4번씩.. 그러면 활용하기가 매우 어렵다.

위처럼 구현하면 마지막 아이템이 완전히 보여지게 되는 경우 딱 1번만 콜백을 받기 때문에 여기 저기 응용하기가 쉽다.

아 그리고 위의 리스너를 만들고 연결하는 방법은.. 다들 알겠지만, 아래처럼..

mRecyclerView.addOnScrollListener(onScrollListener);


728x90