[Android/Kotlin] RecyclerView Last Item Check - 리스트 마지막 항목
Notepad96
·2022. 8. 24. 10:53
1. 요약
이번 글에서는 RecyclerView를 사용하여 만들어진 리스트에서 마지막 항목이 되었을 때를 체크하여 동작을 정의하는 방법에 관하여 기술한다.
2. 레이아웃
2-1. activity_main.xml
메인 레이아웃으로서 RecyclerView 1개로 구성하였다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView01"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
2-2. item_list.xml
RecyclerView 리스트에서 보여줄 각 항목(Item)의 대한 레이아웃을 정의한 파일로서 TextView 2개로 구성하였다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/mainText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Main"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/subText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sub"
android:gravity="right"
android:textSize="18sp" />
</LinearLayout>
3. 코드 및 설명
3-1. RecyclerAdapter.kt
RecyclerView의 Adapter로서 각 항목의 Text는 간단하게 항목의 Position 값에 따라 나타내었다.
package com.notepad96.recyclerviewlastitem
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.notepad96.recyclerviewlastitem.databinding.ItemListBinding
class RecyclerAdapter: RecyclerView.Adapter<RecyclerAdapter.MyView>() {
inner class MyView(private val binding: ItemListBinding): RecyclerView.ViewHolder(binding.root) {
fun bind(pos: Int) {
binding.mainText.text = "$pos"
binding.subText.text = "${pos * pos}"
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyView {
val view = ItemListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MyView(view)
}
override fun onBindViewHolder(holder: MyView, position: Int) {
holder.bind(position)
}
override fun getItemCount(): Int {
return 40
}
}
3-2. MainActivity.kt
마지막 항목을 체크하기 위해서는 RecyclerView에 addOnScrollListener를 통하여 RecyclerView.OnScrollListener 리스너를 재정의 해주어야 한다.
recyclerView의 canScrollVertically은 수직 리스트에 사용하여 1이면 하단을, -1이면 상단을 체크한다.
(수평 방향 리스트일 경우 canScrollHorizontally를 사용 가능하며 오른쪽이 1, 왼쪽이 -1을 나타낸다.)
마지막 항목임을 확인하였을 경우 Count 값이 1씩 증가하는 Toast 메시지를 발생하도록 하였다.
package com.notepad96.recyclerviewlastitem
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.notepad96.recyclerviewlastitem.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.recyclerView01.apply {
adapter = RecyclerAdapter()
layoutManager = LinearLayoutManager(context)
}
var count = 0
binding.recyclerView01.addOnScrollListener(object: RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if(!binding.recyclerView01.canScrollVertically(1)
&& newState == RecyclerView.SCROLL_STATE_IDLE) {
Toast.makeText(applicationContext, "Last Item (${count++})", Toast.LENGTH_SHORT).show()
}
}
})
}
}
이렇게 설정해주면 마지막 Item일 경우 충분히 감지되지만, 가끔 연속으로 인식되어 중복으로 발생하게 되는 문제가 발생한다.
따라서 이를 방지하기 위해서 newState(새 상태)가 SCROLL_STATE_IDLE인지를 추가적으로 체크해줌으로써 중복 발생을 방지할 수 있다.
SCROLL_STATE_IDLE은 현재 RecyclerView가 스크롤되지 않는 상태임을 나타내며 이외의 SCROLL STATE에 대한 것은 아래 글을 참조하면 된다.
4. 전체 파일
'Android' 카테고리의 다른 글
[Android/Kotlin] RecyclerView Move to Top - 최상단 이동 (2) | 2022.08.26 |
---|---|
[Android/Kotlin] Animation Programmatically - alpha, translate, scale (0) | 2022.08.25 |
[Android/Kotlin] DataBinding 데이터 바인딩 (0) | 2022.08.21 |
[Android/Kotlin] TabLayout Custom Style - 탭 스타일 (0) | 2022.08.20 |
[Android/Kotlin] TabLayout + ViewPager2 - Slide하여 화면 전환 (0) | 2022.08.18 |