아래는 리사이클러뷰 ClickListener를 공부하기전 사전 지식입니다.
개념-리스트뷰와-리사이클러뷰에서-ViewHolder-패턴-활용
학습을 하기전 필요한 리사이클러뷰 구현 예제코드 링크입니다.
https://github.com/ilil1/RecyclerviewExampleClickListener를 추가하는 몇가지 방법을 다뤄볼 생각입니다. 이것 말고도 다양한 방법들이 존재할 수 있습니다.
1. 변경 전 RecyclerAdapter.kt
class RecyclerAdapter(private val items: ArrayList<Model>) :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title : TextView = itemView.findViewById(R.id.titleText)
val content : TextView = itemView.findViewById(R.id.contentText)
val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)
fun bind(item: Model) {
thumbnail.clear()
title.text = item.title
content.text = item.content
thumbnail.load(item.imageurl, 16f)
}
}
override fun getItemCount() = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
return RecyclerAdapter.ViewHolder(View)
}
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
val item = items[position]
holder.bind(item)
}
}
이전에 작성한 리사이클러뷰 어댑터 코드입니다. 이 코드 내부에 추가되는 코드들이 있습니다 아래에서 소개하겠습니다.
2. 변경 후 RecyclerAdapter.kt
class RecyclerAdapter(private val items: ArrayList<Model>) :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title : TextView = itemView.findViewById(R.id.titleText)
val content : TextView = itemView.findViewById(R.id.contentText)
val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)
fun bind(item: Model) {
thumbnail.clear()
title.text = item.title
content.text = item.content
thumbnail.load(item.imageurl, 16f)
}
}
override fun getItemCount() = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
return RecyclerAdapter.ViewHolder(View)
}
// 1. ClickListener 인터페이스
interface ClickListener {
fun onClick(v: View, position: Int)
}
// 2. MainActivity에서 클릭 시 이벤트 설정
fun setItemClickListener(itemclickListener: ClickListener) {
this.ItemClickListener = itemclickListener
}
// 3. setItemClickListener로 받아온 파라미터 할당
private lateinit var ItemClickListener : ClickListener
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
val item = items[position]
holder.bind(item)
// 4. 리스트 내 항목 클릭 시 onClick() 호출
holder.itemView.setOnClickListener {
ItemClickListener.onClick(it, position)
}
}
}
변경 후 코드입니다 위 코드에 대해서는 MainActivity.kt과 함께 아래에서 설명하겠습니다.
3. 변경 후 MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var recyclerview: RecyclerView
private lateinit var adapter : RecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val list = ArrayList<Model>()
for(i: Int in 1..10) {
var contact = Model("Add ", i.toString(), "https://picsum.photos/200")
list.add(contact)
}
recyclerview = findViewById(R.id.recyclerView)
adapter = RecyclerAdapter(list)
recyclerview.adapter = adapter
recyclerview.layoutManager = LinearLayoutManager(this)
adapter.setItemClickListener(object: RecyclerAdapter.ClickListener {
override fun onClick(v: View, position: Int) {
// ClickListener 작성
Toast.makeText(this@MainActivity,
"${list[position].content}",
Toast.LENGTH_SHORT).show()
}
})
}
}
MainActivity.kt의 경우 변경전과 변경후에 ClickListner를 추가하는 것말고는 달라지는 것이 없습니다.
추가설명.
// 2. MainActivity에서 클릭 시 이벤트 설정 fun setItemClickListener(itemclickListener: ClickListener) { this.ItemClickListener = itemclickListener }
MainActivity에서 리스너 객체를 받아서 호출이 가능할 수 있도록 하기위해 setItemClickListener를 만들어 줍니다.
setItemClickListener의 경우 ClickListener를 파라미터로 받습니다. 그것을 인터페이스로 만들어 줍니다. 인터페이스로 만들고 MainActivity에서 오버라이드 하여서 Click의 기능을 구현해줍니다.
setItemClickListener(itemclickListener: ClickListener)에서 받아온 파라미터는 private lateinit var ItemClickListener : ClickListener 로 할당됩니다.
// 4. 리스트 내 항목 클릭 시 onClick() 호출
holder.itemView.setOnClickListener {
ItemClickListener.onClick(it, position)
} ItemClickListener는 onClick에 View와 position의 값을 넘겨줘서 이벤트가 최종적으로 발생하게 됩니다.
1. 변경 전 RecyclerAdapter.kt
class RecyclerAdapter(private val items: ArrayList<Model>) :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title : TextView = itemView.findViewById(R.id.titleText)
val content : TextView = itemView.findViewById(R.id.contentText)
val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)
fun bind(item: Model) {
thumbnail.clear()
title.text = item.title
content.text = item.content
thumbnail.load(item.imageurl, 16f)
}
}
override fun getItemCount() = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
return RecyclerAdapter.ViewHolder(View)
}
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
val item = items[position]
holder.bind(item)
}
}
이전에 작성한 리사이클러뷰 어댑터 코드입니다. 이 코드 내부에 추가되는 코드들이 있습니다 아래에서 소개하겠습니다.
2. 변경 후 RecyclerAdapter.kt
class RecyclerAdapter(private val items: ArrayList<Model>) :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title : TextView = itemView.findViewById(R.id.titleText)
val content : TextView = itemView.findViewById(R.id.contentText)
val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)
fun bind(item: Model) {
thumbnail.clear()
title.text = item.title
content.text = item.content
thumbnail.load(item.imageurl, 16f)
}
fun bindViews(item: Model, listener: ClickListener) {
itemView.setOnClickListener {
listener.onClick(item)
}
}
}
override fun getItemCount() = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
return RecyclerAdapter.ViewHolder(View)
}
// 1. ClickListener 인터페이스
interface ClickListener {
fun onClick(item: Model)
}
// 2. MainActivity에서 클릭 시 이벤트 설정
fun setItemClickListener(itemclickListener: ClickListener) {
this.ItemClickListener = itemclickListener
}
// 3. setItemClickListener로 받아온 파라미터 할당
private lateinit var ItemClickListener : ClickListener
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
val item = items[position]
holder.bind(item)
// 4. 리스트 내 항목 클릭 시 onClick() 호출
holder.bindViews(item, ItemClickListener)
}
}
3. 변경 후 MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var recyclerview: RecyclerView
private lateinit var adapter : RecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val list = ArrayList<Model>()
for(i: Int in 1..10) {
var contact = Model("Add ", i.toString(), "https://picsum.photos/200")
list.add(contact)
}
recyclerview = findViewById(R.id.recyclerView)
adapter = RecyclerAdapter(list)
recyclerview.adapter = adapter
recyclerview.layoutManager = LinearLayoutManager(this)
adapter.setItemClickListener(object: RecyclerAdapter.ClickListener {
override fun onClick(item: Model) {
// 클릭 시 이벤트 작성
Toast.makeText(this@MainActivity,
"${item.content}",
Toast.LENGTH_SHORT).show()
}
})
}
}
MainActivity.kt의 경우 이전에는 view와 position을 파라미터로 가졌다면 이번에는 Model을 파라미터로 가지게 됩니다.