본문 바로가기
Developer/Android, Java

[안드로이드] EndlessRecyclerViewScrollListener 적용하기

by Doony 2019. 5. 21.

RecyclerView를 사용하다보면 리스트가 끝없이 이어지는 경우가 있습니다. 서버에서 한번에 모든 데이터를 받아 앱에 띄우기엔 시간이 너무 오래 소요되기 때문에, 보통은 서버단계에서부터 page를 나눠서 관리하는 것이 일반적인데요.

이번 포스팅에서는 서버에서 데이터를 특정 갯수로 분할하여 page식 관리를 할 때, 앱에서 처리하는 방법에 대해 알아보겠습니다. 바로 EndlessRecyclerViewScrollListener를 이용하는 방법입니다. (상세 내용은 여기)

EndlessRecyclerViewScrollListener는 사용자의 스크롤이 최하단까지 내려왔을 때, 이를 인지하여 특정 메소드를 실행하는 방식으로 구성되어 있습니다.
아래는 위 사이트에서 가져온 코드 샘플입니다.

public class MainActivity extends Activity {
    // Store a member variable for the listener
    private EndlessRecyclerViewScrollListener scrollListener;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       // Configure the RecyclerView
       RecyclerView rvItems = (RecyclerView) findViewById(R.id.rvContacts);
       LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
       rvItems.setLayoutManager(linearLayoutManager);
       // Retain an instance so that you can call `resetState()` for fresh searches
       scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) {
           @Override
           public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
               // Triggered only when new data needs to be appended to the list
               // Add whatever code is needed to append new items to the bottom of the list
               loadNextDataFromApi(page);
           }
      };
      // Adds the scroll listener to RecyclerView
      rvItems.addOnScrollListener(scrollListener);
  }
 
  // Append the next page of data into the adapter
  // This method probably sends out a network request and appends new data items to your adapter. 
  public void loadNextDataFromApi(int offset) {
      // Send an API request to retrieve appropriate paginated data 
      //  --> Send the request including an offset value (i.e `page`) as a query parameter.
      //  --> Deserialize and construct new model objects from the API response
      //  --> Append the new data objects to the existing set of items inside the array of items
      //  --> Notify the adapter of the new items made with `notifyItemRangeInserted()`
  }
}
cs

onLoadMore 메소드에 서버를 재호출하는 메소드를 넣어주면 됩니다. 위 코드에서는 loadNextDataFromApi로 명명하여 사용하고 있습니다. 특히 page는 스크롤이 아래 다을수록, 1씩 증가합니다. 따라서 서버를 호출하는 메소드를 사용할 때, 이 page를 이용해야합니다. 상황에 맞게 코드를 변경하여 사용하시면 됩니다. 아래는 제가 사용한 예시입니다.

  • 서버에서 한번에 호출하는 아이템 수: 10개
     
        public void loadNextDataFromApi(int page) {
            if ((page) * itemInOnePage < totalItemCount) {
                getServerData(page); // GET 호출
            } else {
                // 데이터 다 불러옴.
            }
        }
     
    cs

여기서 itemInOnePage는 10개이고, totalItemCount는 서버에서 가지고 있는 전체 데이터의 수입니다. 코드를 보시면, 서버를 호출하기 전에 호출하는 데이터의 수가 마지막 페이지인지를 계산하고 있습니다. 아직 불러올 데이터가 남았을 경우에만 서버를 호출하기 위해서인데요. 이런 과정이 없을 경우, 스크롤을 내릴때마다 계속 서버를 호출하게 될 것이며, 나중에 page가 서버의 page수를 초과할 경우, 경우에 따라 오류가 발생할 수 있습니다. 따라서 서버를 구성할 때, 전체 갯수가 몇개인지는 파악할 수 있어야합니다.

댓글