안드로이드 세계

[Android] Recycler View - Step 2 본문

안드로이드(Android)/코틀린(Kotlin)

[Android] Recycler View - Step 2

리안94 2021. 1. 15. 15:24

이번 포스팅엔 RecyclerView에 클릭이벤트를 넣어볼 것이다.

 

이전 포스팅

ryan94.tistory.com/11

 

[Android] Recycler View - Step 1

리사이클러뷰나 리스트뷰는 리스트형태의 뷰로 보여주기위해 사용되는데, 차이점은 다음과같다. 리사이클러뷰 관련으로 4종류의 포스팅을 작성할 것인데, 이번 포스팅은 기본적인 리사이클러

ryan94.tistory.com

 

클릭이벤트엔 두 가지 방법이 있는데, 뷰 홀더 내에서 처리하는 것과 인터페이스를 구현하여 콜백을 이용하는 방법이 있다.

 

1. 인터페이스 이용

메인 xml은 변화가 없다.

 

메인 액티비티는 다음과 같이 변경한다.

class MainActivity : AppCompatActivity(), AnimalAdapter.ItemClickListener {

    private lateinit var animalAdapter: AnimalAdapter
    private lateinit var animal: MutableList<Animal>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setData()
        initRecyclerView()
    }

    private fun initRecyclerView() {
        animalAdapter = AnimalAdapter(animal, this) // 커스텀어뎁터
        val layoutManager = LinearLayoutManager(this) // 레이아웃메니저 설정
        findViewById<RecyclerView>(R.id.animalRecyclerView).apply {
            this.setHasFixedSize(true) // 모든아이템의 크기가 동일한 경우 true 아닌경우 false
            this.layoutManager = layoutManager
            this.adapter = animalAdapter
        }
    }

    //Sample Data
    private fun setData() {
        animal = mutableListOf()
        animal.add(Animal("Cat", "나비", "010-0000-0000"))
        animal.add(Animal("Cat", "나나", "010-0000-0001"))
        animal.add(Animal("Cat", "냐옹", "010-0000-0002"))
        animal.add(Animal("Cat", "별이", "010-0000-0003"))
    }
    
    override fun onItemClick(view: View, position: Int) { // 클릭이벤트 콜백
        Toast.makeText(
            this@MainActivity,
            "이름: ${animal[position].name} 연락처: ${animal[position].phoneNumber}",
            Toast.LENGTH_SHORT
        ).show()
    }

    override fun onItemLongClick(view: View, position: Int) {
        Toast.makeText(
            this@MainActivity,
            "이름: ${animal[position].name} 연락처: ${animal[position].phoneNumber}",
            Toast.LENGTH_SHORT
        ).show()
    }
}

 

커스텀 어뎁터는 다음과 같이 변경한다.

class AnimalAdapter(
    private var animalsData: MutableList<Animal>,
    private val listener: ItemClickListener
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

	interface ItemClickListener {
        fun onItemClick(view: View, position: Int)
        fun onItemLongClick(view: View, position: Int)
    }

    inner class CatViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bind(animalsData: Animal) {
            itemView.findViewById<ImageView>(R.id.type).setImageResource(R.mipmap.cat)
            itemView.findViewById<TextView>(R.id.animalName).text = animalsData.name
            itemView.findViewById<TextView>(R.id.phoneNumber).text = animalsData.phoneNumber
            
            itemView.findViewById<ConstraintLayout>(R.id.parentView).setOnClickListener {
                listener.onItemClick(it, adapterPosition)
            }

            itemView.findViewById<ConstraintLayout>(R.id.parentView).setOnLongClickListener {
                listener.onItemLongClick(it, adapterPosition)
                true
            }
            
        }
    }
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        // Connect Xml
        val view = LayoutInflater.from(parent.context).inflate(R.layout.catlistdata, parent, false)
        return CatViewHolder(view)
    }

    override fun getItemCount(): Int {
        //List is Null or Empty size = 0 else List size
        return if (animalsData.isNullOrEmpty()) 0 else animalsData.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if(holder is CatViewHolder)
            holder.bind(animalsData = animalsData[position])
    }
}

 

2. 뷰 홀더 내에서 처리하는 방법

 

메인 xml과 액티비티는 변화가 없다.

 

커스텀 어뎁터는 다음과 같이 변경한다.

 

class AnimalAdapter(
    private var animalsData: MutableList<Animal>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private lateinit var context: Context

    inner class CatViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bind(animalsData: Animal) {
            itemView.findViewById<ImageView>(R.id.type).setImageResource(R.mipmap.cat)
            itemView.findViewById<TextView>(R.id.animalName).text = animalsData.name
            itemView.findViewById<TextView>(R.id.phoneNumber).text = animalsData.phoneNumber
            
            itemView.findViewById<ConstraintLayout>(R.id.parentView).setOnClickListener {
                Toast.makeText(
            	context,
            	"이름: ${animal[position].name} 연락처: ${animal[position].phoneNumber}",
            	Toast.LENGTH_SHORT
                ).show()
            }

            itemView.findViewById<ConstraintLayout>(R.id.parentView).setOnLongClickListener {
                Toast.makeText(
            	context,
            	"이름: ${animal[position].name} 연락처: ${animal[position].phoneNumber}",
            	Toast.LENGTH_SHORT
                ).show()
                true
            }
            
        }
    }
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        // Connect Xml
        context = parent.context
        val view = LayoutInflater.from(context).inflate(R.layout.catlistdata, parent, false)
        return CatViewHolder(view)
    }

    override fun getItemCount(): Int {
        //List is Null or Empty size = 0 else List size
        return if (animalsData.isNullOrEmpty()) 0 else animalsData.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if(holder is CatViewHolder)
            holder.bind(animalsData = animalsData[position])
    }
}

 

결과는 다음과 같다.

 

다음 포스팅에는 추가 삭제 이벤트를 추가할 것이며, 1번째 방법을 이용할 것이다.

Comments