📌구현방법
- RecyclerView 생성
- Scroll이 끝에 닿는 것을 감지하여 닿았을 경우 데이터에 NULL 추가 후에 Adapter에 알림
- 일정 시간이 지나면, NULL 제거 후 새로운 데이터 추가하고 Adapter에 알림.
ContentsListActivity.kt
class ContentsListActivity : AppCompatActivity() {
private lateinit var binding: ActivityContentsListBinding
private var dtoList :ArrayList<UnitsDto> = ArrayList()
private var items: ArrayList<UnitsDto?> = ArrayList()
private lateinit var mMapLayoutManager: LinearLayoutManager
private lateinit var mListAdapter: RecyclerViewAdapter
private lateinit var mRecyclerView: RecyclerView
val mainDispatcher: CoroutineDispatcher = Dispatchers.Main
private var isLoading =false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityContentsListBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.apply {
lifecycleOwner = this@ContentsListActivity
activity = this@ContentsListActivity
}
setData()
initAdapter()
initScrollListener()
}
private fun setData(){
dtoList= intent.getSerializableExtra(EXTRA_TITLE) as ArrayList<UnitsDto>
for (i in 0 until 10){
items.add(dtoList[i])
}
}
//1. RecyclerView 생성
private fun initAdapter(){
mListAdapter = RecyclerViewAdapter(items)
mMapLayoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = mListAdapter
}
// 2. scroll이 끝에 닿으면 데이터에 null 추가 및 Adapter에 알림
private fun initScrollListener(){
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if(!isLoading){
if ((recyclerView.layoutManager as LinearLayoutManager?)!!.findLastCompletelyVisibleItemPosition() == items.size - 1){
Log.e("true", "True")
moreItems()
isLoading = true
}
}
}
})
}
//3. null 제거 후 새로운 데이터 추가 및 Adapter에 알림
fun moreItems(){
mRecyclerView = binding.recyclerView
val runnable = Runnable {
items.add(null)
mListAdapter.notifyItemInserted(items.size -1)
}
mRecyclerView.post(runnable)
CoroutineScope(mainDispatcher).launch {
delay(2000)
val runnable2= Runnable{
items.removeAt(items.size - 1)
val scrollPosition = items.size
mListAdapter.notifyItemRemoved(scrollPosition)
var currentSize = scrollPosition
var nextLimit = currentSize+10
Log.e("hello", "${nextLimit}")
if (currentSize < dtoList.size-10){
while (currentSize-1<nextLimit){
items.add(dtoList[currentSize])
currentSize++
}
}else{
while (currentSize!=dtoList.size){
items.add(dtoList[currentSize])
currentSize++
}
}
mListAdapter.updateItem(items)
isLoading = false
}
runnable2.run()
}
}
}
RecyclerViewAdapter.kt
class RecyclerViewAdapter(items: ArrayList<UnitsDto?>?) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), Filterable
{
companion object {
private const val TYPE_ITEM = 0
private const val TYPE_LOADING = 1
}
private var context:Context? = null
private var unFilteredList = items
private var filteredList = items
override fun getItemCount(): Int {
return if (filteredList == null){
0
}else{
filteredList?.size!!
}
}
override fun getItemViewType(position: Int): Int {
return when (filteredList?.get(position)) {
null -> TYPE_LOADING
else -> TYPE_ITEM
}
}
fun updateItem(list:ArrayList<UnitsDto?>?){
this.filteredList = list
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
context = parent.context
if (viewType == TYPE_ITEM){
val binding = RecycleritemLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ItemViewHolder(binding)
}else{
val binding = ItemLoadingBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return LoadingViewHolder(binding)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is ItemViewHolder){
val item = filteredList?.get(position)
val itemHolder = holder as ItemViewHolder
itemHolder.bind(item!!)
}else if (holder is LoadingViewHolder){
}
}
// 아이템뷰에 프로그레스바가 들어가는 경우
inner class LoadingViewHolder(var binding: ItemLoadingBinding) :
RecyclerView.ViewHolder(binding.root) {
}
inner class ItemViewHolder(var binding: RecycleritemLayoutBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: UnitsDto){
binding.nameTxtView.text = "item"
binding.typeTxtView.text = item.type
if (item.progress == 100){
binding.progressTxtView.setTextColor(Color.parseColor("#B0FFFF"))
}
binding.progressTxtView.text = ("${item.progress}% 완료")
Glide.with(context!!)
.load(item.thumbnail)
.apply(RequestOptions.bitmapTransform(RoundedCorners(15)))
.thumbnail(0.5f)
.into(binding.imgView)
binding.imgView.clipToOutline = true
}
}
}