๊ธฐ๋ณธ์ ์ผ๋ก RecyclerView์์ ์ ์ฉํ๋ฉฐ ์ธ ๋จ๊ณ๋ก ์ดํดํ๋ฉด ๋๋ค.
- ์คํฌ๋กค์ด ๋์ ๋ฟ์์ ๊ฒฝ์ฐ null์ ์ถ๊ฐํ๊ณ ์ด๋ํฐ์ ์๋ฆฐ๋ค.(onScrollListener)
- ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ ํ
- null item ์ ๊ฑฐ ํ ํ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ์ด๋ํฐ์ ์๋ฆฐ๋ค.
๊ฒ์์ ํด๋ณด๋ ๋๋ค์๊ฐ ์๋ฒ์์ API๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๊ฒ ๋๋ค์์ ๋ด์ฉ์ด์๋ค. ๋ฌผ๋ก ๋ด๊ฐ ๊ฒ์์ ์ ํ์ง ๋ชปํ์ ๊ฐ๋ฅ์ฑ์ด ๋ ๋์ง๋ง ์ผ๋จ ๋๋ ์๋ฒ์์ ํต์ ์์ด ๋ก์ปฌ์์๋ง ๋ง๋ค์ด๋ดค๋ค. ์ฐธ๊ณ ์๋ฃ๋ ์ธ๋ํ๋์ ์ ํ๋ธ ์์์ด๋ค. ์๋ ๊ธ๋ ๋งค์ฐ ๋์๋๋ค
Adapter์์ getItemViewType ๋ฉ์๋์ recyclerview์์์ scrollListener ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
const val ITEM = 1
const val LOADING = 0
class RvAdapter(val items: MutableList<String?>) : RecyclerView.Adapter<ViewHolder>() {
// ๋น ๋ฅธ ๊ตฌํ์ ์ํด ViewHolder๋ค์ inner๋ก ์ ์ธํ๋ค
inner class ItemViewHolder(itemView: View) : ViewHolder(itemView) {
fun bindItems(item: String) {
val message = itemView.findViewById<TextView>(R.id.rv_item_tv)
message.text = item
}
}
inner class LoadingViewHolder(itemView: View) : ViewHolder(itemView) {
val progressBar = itemView.findViewById<ProgressBar>(R.id.rv_loading_pb)!!
}
override fun getItemViewType(position: Int): Int {
return if (items[position] != null) {
ITEM
} else {
LOADING
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return if (viewType == ITEM) {
val view = LayoutInflater.from(parent.context).inflate(R.layout.rv_item, parent, false)
ItemViewHolder(view)
} else {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.rv_loading, parent, false)
LoadingViewHolder(view)
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (holder is ItemViewHolder) {
holder.bindItems(items[position]!!)
}
}
override fun getItemCount(): Int {
return items.size
}
}
ViewHolder๋ฅผ 2๊ฐ๋ฅผ ๋ง๋ ๋ค.
Item์ ๋์ธ ๋ทฐํ๋, progressbar๋ฅผ ๋์ธ ๋ทฐํ๋. ๋ง๋ค์ด๋ ๋ทฐํ๋๋ฅผ onBindViewHolder์์ ์ค๋งํธ ์บ์คํธ๋ฅผ ์ํด is๋ก ์ฒ๋ฆฌํ๋ค.
onCreateViewHolder์์ viewType์ ๋ฐ์์์๋๋ฐ, ์ด viewType์ ๋ง๋ค์ด์ฃผ๊ธฐ์ํด getItemViewType ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผํ๋ค. ์์ดํ ์ด null์ด๋ฉด loading์ผ๋ก, null์ด ์๋๋ฉด item์ผ๋ก ํ์ ์ ๋ฐํ์์ผ ๊ฐ๊ฐ์ ๋ง๋ ๋ทฐํ๋์ ์ฐ๊ฒฐ์์ผ์ค๋ค.
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
var isLoading = false
private val testItems = mutableListOf<String?>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
for(i in 1 until 10){
testItems.add("dummy item $i")
}
binding.rv.layoutManager = LinearLayoutManager(baseContext)
binding.rv.adapter = RvAdapter(testItems)
binding.rv.addOnScrollListener(object : RecyclerView.OnScrollListener(){
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = binding.rv.layoutManager as LinearLayoutManager
if(!isLoading){
if(!binding.rv.canScrollVertically(1)){
isLoading = true
getMoreData()
}
}
}
})
}
private fun getMoreData() {
testItems.add(null)
binding.rv.adapter?.notifyItemInserted(testItems.size - 1)
testItems.removeAt(testItems.size - 1)
val currentSize = testItems.size
for(i in currentSize+1 until currentSize+10){
testItems.add("dummy item $i")
}
binding.rv.adapter?.notifyDataSetChanged()
isLoading = false
}
}
getMoreData ๋ฌดํ์คํฌ๋กค์ ์๋๊ณผ์ ์ด๋ค. canScrollVertically์ ์ธ์๋ก ๋ฐฉํฅ์ด ๋ค์ด๊ฐ๋๋ฐ, ์ต์๋จ์ -1, ์ตํ๋จ์ 1์ด ๋ค์ด๊ฐ๋ค.
- ๋ฐ์ดํฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ testItems์ null์ ์ถ๊ฐํด์ progressbar๋ฅผ ๋์ด๋ค.
- notifyItemInserted๋ก ํ์ฌ progressbar์์น์ ์์ดํ ์ด ๋ค์ด์ฌ ๊ฒ์ด๋ผ๊ณ ์ด๋ํฐ์ ์๋ ค์ค๋ค.
- null ์ถ๊ฐํ ๊ฒ์ ์ญ์ ํ๊ณ
- ํ์ฌ index๋ฅผ ์ ์์์ง์ ์ผ๋ก ๋ง๋ ๋ค.
- dataset์ ๋ณํ๊ฐ ์๊ฒผ์ผ๋ notifyDatasetChanged๋ก ์ด๋ํฐ์ ๋ ์๋ ค์ฃผ๊ณ
- ๋ฐ์ดํฐ๊ฐ ๋ค ๋ค์ด์์ผ๋ isLoading์ false๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
์ด๋ ์คํฌ๋กค์์ ์ค์ํ ์ ์๋ ๋ถ๋ถ์ด isLoading์ getMoreData ์ดํ์ ๋๋ ๊ฒ์ด๋ค.
isLoading = true๋ฅผ ํจ์ ํธ์ถ์ดํ์ ๋๋ฒ๋ฆฌ๋ฉด ์ต์ด 1ํ๋ง ์๋ํ๊ณ isLoading๊ฐ์ด ํญ์ true์ด๊ธฐ ๋๋ฌธ์ ๋ฌดํ์คํฌ๋กค์ด ์๋๋ค. diffutil์ ์ฌ์ฉํ๊ฒ๋๋ฉด notify๊ณผ์ ์ ๊ทธ๋ฅ submitList๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
"๋๊ธ, ๊ณต๊ฐ ๋ฒํผ ํ ๋ฒ์ฉ ๋๋ฅด๊ณ ๊ฐ์ฃผ์๋ฉด ํฐ ํ์ด ๋ฉ๋๋ค"
'Android ๐ฅ๏ธ > ์ฝ์งโ๏ธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
LiveData ์์๋ณด๊ธฐ (0) | 2024.04.10 |
---|---|
์ง๋ ฌํ - Parcelize, Parcelable, Serializable (0) | 2024.04.05 |
ListAdapter - DiffUtil ์ฝ์ง (0) | 2024.04.03 |
[๋ฒ๊ทธ/์ค๋ฅ] Uri(Url) encoding/decoding - API ์ฌ์ฉ์ (0) | 2024.03.29 |
๋ฉํฐ๋ชจ๋ ๋์ ๊ธฐ(3) - Kotlin DSL, buildSrc (0) | 2023.12.15 |