Android Studio

[Android/kotlin] Recyclerview Click

혁준 2022. 4. 19. 10:30

이번 글은 recyclerview click 에 대한 글입니다. 

 

recyclerview 는 listview 와 명확한 차이가 존재합니다. recyclerview는 listview와 달리 setOnItemClickListener() 메소드와 같은 기능을 직접 코드로 작성을 해주어야 합니다! 

 

이 점에 유의하여 코드를 작성해주어야 합니다. 그럼 글 시작하겠습니다. 

 

 아래의 사진은 블로그에 글을 쓰면서 만든 파일들의 전체적인 구조입니다. 코드를 참고하실 때, 도움이 될 것 같아 남깁니다.

이제 본격적으로 코드 작성을 해보겠습니다.

// activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout 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/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/item_main"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

activity_main.xml 입니다. 여기에서는 recyclerview 에 대한 코드만 작성해주면 됩니다. 

// item_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="110dp"
    xmlns:app="http://schemas.android.com/apk/res-auto">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:text="name"
            android:textStyle="bold"
            android:layout_marginStart="30dp"
            android:textSize="40sp"/>

        <TextView
            android:id="@+id/tv_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/tv_name"
            app:layout_constraintStart_toStartOf="parent"
            android:text="age"
            android:textSize="40sp"
            android:layout_marginStart="30dp"
            />

        <ImageView
            android:id="@+id/iv_delete"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:src="@drawable/delete_24"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            />


</androidx.constraintlayout.widget.ConstraintLayout>

item_main.xml 에서는 recyclerview에 들어갈 item 들에 대한 디자인을 해줍니다. (실제 이미지를 보고 싶으시다면, 하단의 실제 테스트 동영상을 확인하시면 됩니다. )

data class User(
    val name: String,
    val age: String
)

이번 프로젝트에서 사용할 data class 입니다. recyclerview에 표현할 데이터를 이름, 나이로 간단하게 설정을 해주었기 때문에, 이 data class 에서도 name, age 만 존재합니다. 

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class MainAdapter() : RecyclerView.Adapter<MainAdapter.MainViewHolder>() {

    // 클릭 이벤트
    interface OnItemClickListener {
        fun onItemClick(view: View, data: User, pos: Int )
        fun deleteClick(view: View, data: User, pos: Int)
    }
    private var listener: OnItemClickListener? = null
    fun setOnItemClickListener(listener: OnItemClickListener) {
        this.listener = listener
    }

    var user = mutableListOf<User>()

    inner class MainViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textName: TextView = itemView.findViewById(R.id.tv_name)
        val textAge: TextView = itemView.findViewById(R.id.tv_age)
        val iv: ImageView = itemView.findViewById(R.id.iv_delete)

        fun bind(user: User) {
            textName.text = user.name
            textAge.text = user.age
            val pos = adapterPosition

            itemView.setOnClickListener {
                listener?.onItemClick(itemView,user,pos)
            }
            iv.setOnClickListener {
                listener?.deleteClick(iv,user,pos)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {
        return MainViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_main,parent,false))
    }

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

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

이제 adapter 입니다. 여기에서는 interface를 사용하여 클릭 가능 기능 넣어주어야 합니다. 그 후 click의 기능에 따라서 간단하게 함수를 넣어줍니다.

이후에 fun setOnItemClickListener 를 활용하여 listener 를 연결시켜 줍니다. 

그 후 viewHolder class 의 fun bind() 에서 view 에 대한 click 처리를 해줍니다. 

 

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import com.example.recyclerviewtest.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    lateinit var binding: ActivityMainBinding
     var mainAdapter = MainAdapter()
    val user = mutableListOf<User>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        initRecyclerview()
        temporaryList()
        recyclerViewClick()
    }

    private fun initRecyclerview() {
        val recyclerView = binding.recyclerview
        recyclerView.adapter = mainAdapter

    }
    fun temporaryList() {
        user.apply {
            add(User("david", "25"))
            add(User("rabbit", "3"))
            add(User("Gom", "5"))
            // mainAdapter.user = user
            // mainAdapter.notifyDataSetChanged()
            mainAdapter.user = user
            mainAdapter.notifyDataSetChanged()
        }
    }

    fun recyclerViewClick() {
        mainAdapter.setOnItemClickListener(object: MainAdapter.OnItemClickListener{
            override fun onItemClick(view: View, data: User, pos: Int) {
                Toast.makeText(this@MainActivity, "click", Toast.LENGTH_SHORT).show()
            }

            override fun deleteClick(view: View, data: User, pos: Int) {
                Toast.makeText(this@MainActivity, "delete", Toast.LENGTH_SHORT).show()
            }

        })
    }
}

이제 MainActivity 입니다. 

fun initRecyview() 에서는 recyclerview adapter 간의 연결을 해줍니다. 

fun temporaryList() 에서는 이번 recyclerview click에서 사용될 데이터들을 임의로 입력해줍니다. 

 

마지막으로 fun recyclerViewClick 에서는 클릭 이벤트를 처리해줍니다.

저는 item, delete 이미지 클릭시 toast message 가 나오게끔 설정을 해주었습니다. 

toast message 이외에도 intent를 사용하여 특정 화면으로 넘어가거나, 데이터를 넘겨주는 등 다양한 기능들을 수행할 수 있습니다. 😄

 

 

실제 테스트 영상입니다.

 

읽어주셔서 감사합니다. 

 

구글링을 하였을 때, kotlin 으로 작성된 recyclerview click 글들이 많이 없어서 글을 작성하게 되었습니다. 

미숙한 글이지만 이 글이 kotlin 으로 recyclerview click 을 공부하시는 분들께 조금이나마 도움이 되었으면 좋겠네요! 

 

오늘도 행복한 하루 보내세요 :)