본문 바로가기
TeamProject/ImadAndroid

리사이클러뷰 스크롤시 페이지 요청

by 둥글레차35 2024. 4. 24.

작품 검색 요청을 진행하기 위하여 뷰를 스크롤 시 새로운 데이터를 받아오도록 진행을 하였다.



1. 먼저 스크롤시에 기존 데이터를 삭제하지 않고 추가해주는 방식으로 변경


해당 경우의 경우 우선 리사이클러뷰의 List -> MutableList로 변경해 주었다. 
- 새로운 검색어가 들어오는 경우에는 setList함수를 사용하여 처음 들어온 데이터로 리스트를 변경

fun setList(list: MutableList<Result>) {
    searchList = list
    notifyDataSetChanged()
}

 


- 기존의 검색어에서 스크롤만을 하였을 경우 addItems 함수를 사용하여 기존에 있던 데이터를 추가해 주는 방식으로 진행 하였다.

fun addItems(newItems: List<Result>) {
    searchList.addAll(newItems)
    notifyDataSetChanged()
}



스크롤시 행동을 제어

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)
        if (!recyclerView.canScrollVertically(1)) {
               // 리사이클러뷰의 맨 아래에 도달했을때의 이벤트
               } else {
                   Log.d("testt", "none Text")
               }
           
        } else if (!recyclerView.canScrollVertically(-1)) {
         // 위로 올릴때 사용할 기능

        }
    }



2. 문제점

해당 방법을 사용하여 스크롤시 정상적으로 데이터를 불러오는데는 성공하였다. 하지만 직접 테스트 시 2가지 문제점이 있었다.

- 아무런 텍스트가 없을때 아래로 스크롤시 요청이 발생
- 작품 페이지 리스트가 이미 끝났음에도 스크롤시 요청이 발생


해당 문제점들의 경우에

텍스트가 없을 경우는 if문을 추가하여 처리하였다.

private fun scrollStateChanged() {
    recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            //아래로 내릴때
            if (!recyclerView.canScrollVertically(1)) {
                searchJob?.cancel()
                searchJob = lifecycleScope.launch {
                    delay(1500)
                    val query = search.text.toString()
                    // 아무 텍스트도 없을때 내릴시에는 아무 행동이 없도록
                    if (!query.isEmpty()) {
                        searchRequest2(query)
                        Log.d("testt", "아래")
                    } else {
                        Log.d("testt", "none Text")
                    }
                }
                // 위로 올릴때
            } else if (!recyclerView.canScrollVertically(-1)) {
                searchJob?.cancel()
                searchJob = lifecycleScope.launch {
                    delay(1500)
                    Log.d("testt", "위")
                }
            }
        }
    })
}



그리고 리스트 페이지가 이미 종료된 경우에는 검색어로 첫 요청시 totalPage를 저장하고 currentPage보다 작을 경우 아무런 처리도 하지 않도록 수정하였다.

var totalPage: Long? = 0 // 전역변수

        ++currentPage // 전역변수 currentPage를 1씩 증감
        if (totalPage!!.toInt() >= currentPage){
            TokenRetrofitManager.getInstance(applicationContext).search(params) { response ->
                if (response.isSuccessful) {
                    val searchResponse =
                        response.body()?.data?.results ?: emptyList() // // 서버 응답에서 받은 데이터
                    val mutableSearchList = searchResponse!!.toMutableList()
                    adapter.addItems(mutableSearchList)
                    Log.d("testt", "" + searchResponse)
                } else {
                    Log.d("testt", "작품 검색 요청 실패")
                }
            }
        }


결과물

 

댓글