2021. 1. 22. 00:48ㆍ📱Android/👩🏻💻 Android 개발 일지
RecyclerView 첫번째 시리즈에 이어 두번째 시리즈인 클릭 리스너를 추가하여 리사이클러뷰 아이템에 각각 클릭 이벤트를 적용하는 방법에 대해 적어보려고 합니다 : )
RecyclerView 만드는 방법에 대해 궁금하시다면 !? 아래 글을 먼저 읽고 와주세요!
RecyclerView를 사용하면서 RecyclerView의 각각 아이템을 클릭하면 새로운화면으로 전환되는 것을 많이 보신 적 있을것 같습니다.
2가지의 방법을 소개해보고자 합니다.
1. RecyclerView Adapter에서 Click 이벤트 적용하기
2. RecyclerView가 사용되는 Activity나 Fragment에서 Click 이벤트 적용하기
1. RecyclerView Adapter에서 Click 이벤트 적용하기
📌 ProfileDetailActivity.kt 만들어주기
리사이클러뷰의 아이템을 클릭하면 전환되는 화면인 ProfileDetailActivity.kt를 하나 추가해주었습니다.
ProfileDetailActivity.xml
RecyclerView에서 ImageView와 TextView를 전달받아 보여줄 것이기 때문에 ImageView와 TextView를 하나씩 배치하였습니다.
<?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"
tools:context=".ProfileDetailActivity">
<ImageView
android:id="@+id/img_profile"
android:layout_width="200dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="@color/black"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/img_profile"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
📌Adpater ViewHolder에 클릭 이벤트 적용해주기
RecyclerView Adapter 에서 클릭이벤트를 적용하는 방법은 비교적 간단합니다 !
저번 리사이클러뷰 시리즈에서 만들었던 ProfileAdpater에 추가해주도록 하겠습니다.
RecyclerView Adpater안에 만들어놨던 InnerClass인 ViewHolder의 bind 함수 안에 추가해주시면 됩니다 : )
putExtra(item)으로 원하는 데이터를 ProfileDetatilActivity에 전달할 수 있습니다. 저는 Serializable을 이용하여 데이터 자체를 전달해주었습니다.
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val txtName: TextView = itemView.findViewById(R.id.tv_rv_name)
private val txtAge: TextView = itemView.findViewById(R.id.tv_rv_age)
private val imgProfile: ImageView = itemView.findViewById(R.id.img_rv_photo)
fun bind(item: ProfileData) {
txtName.text = item.name
txtAge.text = item.age.toString()
Glide.with(itemView).load(item.img).into(imgProfile)
itemView.setOnClickListener {
Intent(context, ProfileDetailActivity::class.java).apply {
putExtra("data", item)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.run { context.startActivity(this) }
}
}
}
📌 ProfileDetailActivity.kt Intent로 전달받은 데이터 연결해주기
위에서 putExtra를 통해 전달한 데이터를 ProfileDetailActivity.kt에서 만들었던 ImageView와 TextView와 연결해주도록 하겠습니다.
getSerializableExtra를 통해 Intent에 같이 전달한 ProfileData를 받을 수 있습니다.
이때 ! 주의할 점은 putExtra("name") 과 getSerializableExtra("name")의 name이 동일해야합니다!
package com.example.recyclerview_ex
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_profile_detail.*
class ProfileDetailActivity : AppCompatActivity() {
lateinit var datas : ProfileData
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile_detail)
datas = intent.getSerializableExtra("data") as ProfileData
Glide.with(this).load(datas.img).into(img_profile)
tv_name.text = datas.name
}
}
이제 클릭이벤트를 연결한 화면을 확인해볼까요!?
아래와 같이 완성되었습니다.
2. RecyclerView가 사용되는 Activity나 Fragment에서 Click 이벤트 적용하기
리사이클러뷰 아이템 클릭시 전환되는 화면인 ProfileDetailActivity는 위에서 구현하였으니 생략하도록 하겠습니다.
위 방법은 Item의 Position이 중요한 경우나 Adpater가 아닌 RecyclerView가 만들어진 Activity나 Fragment에서 존재하는 data를 같이 전달해야할 때 주로 사용합니다.
📌 ProfileAdapter.kt ClickListener Interface 만들어주기
RecyclerView에는 ListView 와 다르게 클릭리스너가 내장되어있지 않습니다! 그래서 추가로 ClickListener역할을 하는 interface를 만들어줘야합니다.
Adpater안에 OnItemClickListener 를 Interface로 만들어주고, ViewHolder에서 연결해주도록 하겠습니다.
Adapter Class안에 적어주시면 됩니다!
interface OnItemClickListener{
fun onItemClick(v:View, data: ProfileData, pos : Int)
}
private var listener : OnItemClickListener? = null
fun setOnItemClickListener(listener : OnItemClickListener) {
this.listener = listener
}
Adapter 내부 Class인 ViewHolder bind 함수 안에 적어주시면 됩니다!
val pos = adapterPosition
if(pos!= RecyclerView.NO_POSITION)
{
itemView.setOnClickListener {
listener?.onItemClick(itemView,item,pos)
}
}
ProfileAdapter.kt 전체
package com.example.recyclerview_ex
import android.content.Context
import android.content.Intent
import android.os.Bundle
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
import com.bumptech.glide.Glide
class ProfileAdapter(private val context: Context) : RecyclerView.Adapter<ProfileAdapter.ViewHolder>() {
var datas = mutableListOf<ProfileData>()
interface OnItemClickListener{
fun onItemClick(v:View, data: ProfileData, pos : Int)
}
private var listener : OnItemClickListener? = null
fun setOnItemClickListener(listener : OnItemClickListener) {
this.listener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(parent.inflate(R.layout.item_recycler_ex))
override fun getItemCount(): Int = datas.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(datas[position])
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val txtName: TextView = itemView.findViewById(R.id.tv_rv_name)
private val txtAge: TextView = itemView.findViewById(R.id.tv_rv_age)
private val imgProfile: ImageView = itemView.findViewById(R.id.img_rv_photo)
fun bind(item: ProfileData) {
txtName.text = item.name
txtAge.text = item.age.toString()
Glide.with(itemView).load(item.img).into(imgProfile)
val pos = adapterPosition
if(pos!= RecyclerView.NO_POSITION)
{
itemView.setOnClickListener {
listener?.onItemClick(itemView,item,pos)
}
}
}
}
}
📌 MainActivity에 Click 이벤트 적용해주기
ProfileAdpater 객체인 profileAdater에서 위에서 만들어준 setOnItemClickListener를 호출해줍니다. 이때 ProfileAdapter.OnItemClickListener의 Interface를 상속받아 함수를 구현해줍니다.
profileAdapter.setOnItemClickListener(object : ProfileAdapter.OnItemClickListener{
override fun onItemClick(v: View, data: ProfileData, pos : Int) {
Intent(this@MainActivity, ProfileDetailActivity::class.java).apply {
putExtra("data", data)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.run { startActivity(this) }
}
})
위와 같은 동일한 작업을 하는 화면을 만드실 수 있습니다!
RecyclerView ClickEvent를 때에 따라 사용하면 좋을 것같습니다 : )
다음 포스팅에서는 AnimationTransition을 적용한 RecyclerView에 대해 작성해보도록 하겠습니다!
'📱Android > 👩🏻💻 Android 개발 일지' 카테고리의 다른 글
[Android/Kotlin] RecyclerView Animation 활용하기 (0) | 2021.01.22 |
---|---|
[Android/Kotlin] RecyclerView 만들기 (7) | 2021.01.14 |
[Android/Kotlin] 간단한 Animation Transition 구현하기 (0) | 2021.01.02 |