DBILITY

안드로이드 RecyclerView 기초 사용법 본문

android/kotlin

안드로이드 RecyclerView 기초 사용법

DBILITY 2024. 3. 5. 14:13
반응형

https://developer.android.com/develop/ui/views/layout/recyclerview?hl=ko

 

RecyclerView로 동적 목록 만들기  |  Views  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. RecyclerView로 동적 목록 만들기 Android Jetpack의 구성요소

developer.android.com

공식처럼 사용하면 되려나

RecyclerView에 표시될 Item의 data class,Layout을 만들고 layoutManager를 지정하고 adapter를 연결한다.

adapter가 중요한데 ListAdapter, ViewHolder, ItemCallback 부분을 잘 보자.

ItemCallback -> ViewHolder -> ListAdapter순으로 구현

액티비티 디자인

// 데이터 클래스
data class Todo(val id: Int, val todo: String, val datetime: Long)

아이템 뷰 디자인

package com.example.myex04

import android.content.DialogInterface.OnClickListener
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.example.myex04.databinding.ActivityMainBinding
import com.example.myex04.databinding.ItemViewBinding
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.concurrent.TimeUnit

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG: String = "LOG"
    }

    private val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    private val datetimeFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
    private val itemList: MutableList<Todo> = mutableListOf()
    private val todoListAdapter: TodoListAdapter = TodoListAdapter {
        Toast.makeText(
            this,
            "${it.id.toString()} , ${it.todo} , ${datetimeFormatter.format(it.datetime)}",
            Toast.LENGTH_SHORT
        ).show()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        try {
            TimeUnit.MILLISECONDS.sleep(2000)

        } catch (ie: InterruptedException) {
            ie.printStackTrace()
        }

        for (idx in 1..100) {
            itemList.add(Todo(idx, "do something~~ $idx", System.currentTimeMillis()))
        }

        Log.d(TAG, itemList.size.toString())

        with(binding) {
            activityMainRecyclerView.apply {
                layoutManager = LinearLayoutManager(binding.root.context)
                itemAnimator = null
                adapter = todoListAdapter
            }
        }

    }

    inner class TodoListAdapter(private val onClickListener: (Todo) -> Unit) :
        ListAdapter<Todo, TodoViewHolder>(TodoDiffCallback()) {
        private lateinit var binding: ItemViewBinding
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
            binding = ItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            return TodoViewHolder(binding, onClickListener)
        }

        override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
            holder.bind(itemList[position])
        }

        override fun getItemCount(): Int {
            return itemList.size
        }
    }

    inner class TodoViewHolder(
        private val binding: ItemViewBinding,
        private val onClickListener: (Todo) -> Unit
    ) : ViewHolder(binding.root) {
        fun bind(todo: Todo) {
            with(binding) {
                itemViewId.text = todo.id.toString()
                itemViewTodo.text = todo.todo
                itemViewDatetime.text = datetimeFormatter.format(todo.datetime)
                root.setOnClickListener {
                    onClickListener(todo)
                }
            }
        }
    }

    inner class TodoDiffCallback : DiffUtil.ItemCallback<Todo>() {
        override fun areItemsTheSame(oldItem: Todo, newItem: Todo): Boolean =
            oldItem.id == newItem.id

        override fun areContentsTheSame(oldItem: Todo, newItem: Todo): Boolean = oldItem == newItem
    }

}

이벤트를 저렇게 주는게 맞는지 모르겠으나 일단은 된다.

실행화면

반응형
Comments