2024.02.01(목) TIL

quinones·2024년 2월 1일

오늘은 다음페이지 자동구현, 무한스크롤을 MVVM패턴으로 옮겼다.

먼저 사용하는곳의 어뎁터에서 addOnScrollListener 오버라이딩하는건 같다.

searchRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)
        val layoutManager = recyclerView.layoutManager as GridLayoutManager
        val visibleItemCount = layoutManager.childCount //화면에보이는 아이템개수
        val totalItemCount = layoutManager.itemCount //어뎁터에설정된 전체아이템개수
        val firstVisibleItemPosition =
            layoutManager.findFirstVisibleItemPosition() //현재화면에 첫번째로보이는 아이템의 포지션
        val isLastItemVisible =
            firstVisibleItemPosition + visibleItemCount >= totalItemCount -1 //마지막아이템이 화면에 보이는지
        if (isLastItemVisible && dy > 0) {
            loadNextPage()
        }
    }
})

어뎁터에 아이템 개수와 전체아이템개수를 구해서 마지막아이템이 화면에 표시되는지, 그리고 스크롤이 아래로 가고있는지 확인하고 true라면 loadNextPage를 불러와준다.

해당 함수는 아래처럼 구현돼있다. 한페이지가 지나면 다음페이지가 로딩되어야하기때문에 첫페이지를 1로 설정하고, 다음에 부를때는 해당페이지가 1씩 늘어나게 구현했다. 검색어를 가져와서 카카오 API를 이용해서 이미지와 동영상을 가져와준다.

private var currentPage = 1
...
private fun loadNextPage() {
    currentPage++
    val searchEdit = binding.searchEdit.text.toString()
    if (searchEdit.isNotBlank()) {
        viewModel.setUpParameter(searchEdit, currentPage)
    }
}

뷰모델

private val _searchParam: MutableLiveData<HashMap<String, String>> = MutableLiveData()
val searchParam: LiveData<HashMap<String, String>> get() = _searchParam
private val _searchResult: MutableLiveData<List<CombinedSearchItem>> = MutableLiveData()
val searchResult: LiveData<List<CombinedSearchItem>> get() = _searchResult
...
fun setUpParameter(input: String, page: Int) {
    val authKey = "KakaoAK ${Contract.API_KEY}"
    _searchParam.value = hashMapOf(
        "Authorization" to authKey,
        "query" to input,
        "sort" to "recency",
        "page" to page.toString(),
        "size" to "20"
    )
}
fun dataFromNetwork(param: HashMap<String, String>) {
    viewModelScope.launch {
        val authKey = "KakaoAK ${Contract.API_KEY}"
        val items = mutableListOf<CombinedSearchItem>()

        val imageResponseData = NetWorkClient.combinedNetWork.getImageResults(authKey, param)
        val videoResponseData = NetWorkClient.combinedNetWork.getVideoResults(authKey, param)

        imageResponseData.searchDocument?.let {
            items.addAll(it.map { CombinedSearchItem(it, SearchItemType.IMAGE) })
        }
        videoResponseData.searchDocument?.let {
            items.addAll(it.map { CombinedSearchItem(it, SearchItemType.VIDEO) })
        }

        items.shuffle()
        items.sortedByDescending {
            when (it.itemType) {
                SearchItemType.IMAGE -> (it.searchItem as SearchDocument).datetime
                SearchItemType.VIDEO -> (it.searchItem as SearchDocumentVideo).datetime
            }
        }

        _searchResult.value = _searchResult.value.orEmpty() + items
    }
}

이렇게해서 이미지와 동영상 검색된 데이터들을 가져와줬다.
마지막 _searchResult.value = _searchResult.value.orEmpty() + items부분에서 오류가 나서 이렇게 수정했는데,
기존의 값을 가져와서(기존 리스트를) 해당 리스트에서 추가된 아이템을 뒤에 붙여줘야한다.
이렇게해야지 기존에 있던 데이터가 삭제되지않고, 아래에 아이템이 추가되서 무한스크롤이 가능해진다.


무한스크롤
자동검색구현
MVVM
mvvm
디자인패턴

profile
이우진

0개의 댓글