유니 코드

[Android] RecyclerView 아이템 클릭이벤트 본문

오늘의 공부는?!/Android

[Android] RecyclerView 아이템 클릭이벤트

꼬물쥰 2022. 8. 9. 22:24

RecyclerView를 사용할 때 아이템을 클릭하면 새로운 화면으로 전환시키는 방법을 알아보자

찾아보니 2가지 방법이 있다

 

1. RecyclerView의 Adapter에서 클릭 이벤트 적용하기

2. RecyclerView가 사용되는 Activity/Fragment에서 클릭 이벤트 적용하기

 

이 글에서는 Adapter에 클릭 이벤트를 적용하는 방법을 사용해보겠다.

아래 코드는 ListFragment에 RecyclerView를 구현해두었고, RecyclerVeiw 아이템을 클릭하면

채팅화면인 MessageActivity로 전환하는 예제이다.

 

● MessageActivity.kt 생성

RecyclerVeiw 아이템 클릭시 전환될 화면을 생성하자

 

activity_message.xml

RecyclerView에서 출발, 도착, 출발시간, 채팅 내역을 String으로 전달받아 보여줄 예정이다

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:padding="10dp">

    <TextView
        android:id="@+id/messageActivity_start"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="5dp"
        android:textAlignment="center"
        app:layout_constraintEnd_toStartOf="@id/messageActivity_dest"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="출발지" />

    <TextView
        android:id="@+id/messageActivity_dest"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="5dp"
        android:textAlignment="center"
        app:layout_constraintEnd_toStartOf="@id/messageActivity_departTime"
        app:layout_constraintStart_toEndOf="@id/messageActivity_start"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="도착지" />

    <TextView
        android:id="@+id/messageActivity_departTime"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="5dp"
        android:textAlignment="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/messageActivity_dest"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="출발시간" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/messageActivity_profiles"
        android:layout_width="380dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:orientation="horizontal"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toTopOf="@id/messageActivity_recyclerview"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/messageActivity_start"
        tools:listitem="@layout/item_recycler_profiles" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/messageActivity_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/messageActivity_profiles"
        tools:listitem="@layout/item_recycler_message" />

    <EditText
        android:id="@+id/messageActivity_editText"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginEnd="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/messageActivity_sendBtn"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/messageActivity_sendBtn"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:paddingStart="8dp"
        android:src="@drawable/ic_baseline_send_24"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/messageActivity_editText"
        app:layout_constraintTop_toTopOf="@id/messageActivity_editText" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

● Adapter의 ViewHolder에 클릭 이벤트 적용

RecyclerView의 Adapter에 이벤트를 추가해보자 나는 ShareListAdapter라는 이름으로 Adapter를 만들었다

Inner class인 ViewHolder 내부에서 itemView에 setOnClickListener를 달아준다

putExtra로 데이터를 intent할 activity에 전달할 수 있는데 그냥 하려고 하니까 putExtra에 에러가 떠서

찾아보니 Model클래스에 Serializable을 해주어야한다

 

    inner class ListItemViewHolder(private val binding: ItemRecyclerListBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(item: Share) {
            binding.listCreatorNickname.text = item.creatorNickname
            binding.listGender.text = item.memberGender
            binding.listStart.text = item.start
            binding.listDest.text = item.dest
            binding.listMember.text = "${item.memberCount} / ${item.memberNum}"
            binding.listTime.text = item.departTime

            when(item.creatorGender){
                "Male" -> binding.listCreatorGender.setImageResource(R.drawable.male)
                "Female" -> binding.listCreatorGender.setImageResource(R.drawable.female)
            }

            if(item.creatorImgUrl.isBlank()){
                binding.listCreatorProfileImage.setImageResource(R.drawable.default_profile)
            }else{
                Glide.with(binding.listCreatorProfileImage.context)
                    .load(item.creatorImgUrl)
                    .into(binding.listCreatorProfileImage)
            }

            itemView.setOnClickListener{
                Intent(context, MessageActivity::class.java).apply {
                    putExtra("data", item)
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                }.run { context.startActivity(this) }
            }
        }
    }

● MessageActivity.kt에서 Intent로 전달받은 데이터 연결하기

putExtra를 통해 전달한 데이터를 연결하기 위해서 getSerializableExtra를 이용한다

class MessageActivity: AppCompatActivity() {
    private lateinit var binding: AcivityMessageBinding
    lateinit var datas: Share

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

        datas = intent.getSerializableExtra("data") as Share

        // datas 에는 생성자 정보, 합승 정보, 참가자 정보
        binding.messageActivityStart.text = "출발 - ${datas.start}"
        binding.messageActivityDest.text = "도착 - ${datas.dest}"
        binding.messageActivityDepartTime.text = "출발시간 - ${datas.departTime}"
        
    }
}

일단 출발, 도착, 출발시간만 연결해두었고 이제 나머지를 연결하러 가야겠다

아래는 실행화면과 ShareListAdapter 전체코드이다

class ShareListAdapter(private val context: Context) :
    RecyclerView.Adapter<ShareListAdapter.ListItemViewHolder>() {
    private val db = FirebaseFirestore.getInstance()
    private var currentList = mutableListOf<Share>()

    init{
        db.collection("shares")
            .orderBy("departTime")
            .addSnapshotListener{querySnapshot, exception ->
            currentList.clear()

            for(snapshot in querySnapshot!!.documents){
                val item = snapshot.toObject(Share::class.java)
                currentList.add(item!!)
            }
            notifyDataSetChanged()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder {
        return ListItemViewHolder(ItemRecyclerListBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }

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

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

    inner class ListItemViewHolder(private val binding: ItemRecyclerListBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(item: Share) {
            binding.listCreatorNickname.text = item.creatorNickname
            binding.listGender.text = item.memberGender
            binding.listStart.text = item.start
            binding.listDest.text = item.dest
            binding.listMember.text = "${item.memberCount} / ${item.memberNum}"
            binding.listTime.text = item.departTime

            when(item.creatorGender){
                "Male" -> binding.listCreatorGender.setImageResource(R.drawable.male)
                "Female" -> binding.listCreatorGender.setImageResource(R.drawable.female)
            }

            if(item.creatorImgUrl.isBlank()){
                binding.listCreatorProfileImage.setImageResource(R.drawable.default_profile)
            }else{
                Glide.with(binding.listCreatorProfileImage.context)
                    .load(item.creatorImgUrl)
                    .into(binding.listCreatorProfileImage)
            }

            itemView.setOnClickListener{
                Intent(context, MessageActivity::class.java).apply {
                    putExtra("data", item)
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                }.run { context.startActivity(this) }
            }
        }
    }
}

 

 

RecyclerView 클릭이벤트 적용하기

Comments