개발 공부/Android / / 2022. 8. 10. 16:06

[Android Kotlin]RecyclerView Adapter 내외부 ClickListener 구현하기(onClick, LongClick)

onClick과 LoginClick을 둘 다 사용해야하는 상황에서 구현해보고나서 정리. 

Adapter 내외부 둘 다 사용이 가능하며 둘 다 반응하도록 구현했을 때는 Adapter 내부에 있는 것이 우선이었다. 

 

1. Adapter 내부에 Interface 생성 

onClick과 LongClick Interface를 생성한다. 

나는 Adapter에서 ViewBinding을 사용했기 때문에 ItemAccountBinding을 받을 수 있도록 오버로딩했다. ViewBinding을 사용하지 않는 상태면 View를 받는 것만 해둬도 된다. 이걸 통해서 외부에서도 itemView에 접근할 수 있다. 

    interface OnClickInterface{ //OnClickListener 인터페이스
        fun onClick(view: View, position: Int) //viewbinding 안했을 때 
        fun onClick(view: ItemAccountBinding, position: Int) //viewbinding을 적용해서 추가함.
    }
    interface OnLongClickInterface{  //LongClick Listener 인터페이스
        fun onLongClick(view: View, position: Int) //viewbinding 안했을 때 
        fun onLongClick(view: ItemAccountBinding, position: Int)//viewbinding을 적용해서 추가함.
    }

2. Adapter 생성자에 각 Interface Object를 받을 수 있도록 파라미터 추가

class AllAccountListAdapter(val context: Context, private val accounts:List<AccountData>,
                            onClick: OnClickInterface,
                            onLongClick: OnLongClickInterface):
    RecyclerView.Adapter<AllAccountListAdapter.ItemViewHolder>(){

3. 받아온 값 선언 및 초기화 

var onClickInterface: OnClickInterface = onClick
var onLongClickInterface: OnLongClickInterface = onLongClick

4. Adapter 내부에 클릭리스너 구현 

둘 중에서 필요한대로 사용하면 된다. 나는 onClick을  ViewHolder에서,  LongClick을 onBindViewHolder 함수에서 썼다. 

4-1. ViewHolder Class에 구현 

ViewHolder 클래스는 inner클래스로 구현. onBind함수 내에서 구현하였다. ViewBinding을 사용하고 있기 때문에 thisBinding이란 변수로 받아서 각각 리스너에 넣어줌. 

	//아이템 뷰홀더
    inner class ItemViewHolder(binding: ItemAccountBinding): RecyclerView.ViewHolder(binding.root){
        val accountName = binding.tvAccountName
        val checkBox = binding.cbAccountCheck
        val thisBinding = binding

        fun onBind(context: Context, item: AccountData, itemPosition: Int){  
            accountName.text = item.name
            
	     //OnClickListener
            itemView.setOnClickListener(View.OnClickListener {
                onClickInterface.onClick(thisBinding, position = itemPosition)
                //실행하고자 하는 코드 입력
            })

            //LongClick Listener
            itemView.setOnLongClickListener(View.OnLongClickListener {
                onLongClickInterface.onLongClick(it, position = itemPosition)
                //실행하고자 하는 코드 입력 
                return@OnLongClickListener true
            })
        }
    }

4-2. onBindViewHolder 함수 내 적용

override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        val item = accounts[position]
        holder.onBind(context, item, position)

        //OnClickListener
        holder.itemView.setOnClickListener(View.OnClickListener {
            onClickInterface.onClick(it, position)
            //실행하고자 하는 코드 입력

        })

        //LongClick Listener
        holder.itemView.setOnLongClickListener(View.OnLongClickListener {
            onLongClickInterface.onLongClick(it, position)
            //실행하고자 하는 코드 입력
            
            return@OnLongClickListener true
        })

    }

 

5.Kotlin 코드 추가 

이 Adapter를 이용해 구현한 RecyclerView가 있는 Kotlin 코드로 이동해서 코드를 추가해 준다. 

Adapter를 생성할 때 필요한 Object를 생성해줘야한다. 

val obj = object: AllAccountListAdapter.OnClickInterface {
    override fun onClick(view: View, position: Int) {
        //Toast.makeText(context,"온클릭",Toast.LENGTH_SHORT).show()
    }
    
    //ViewBinding으로 Adapter를 구현했기 때문에 외부에서 직접 아이템에 영향을 주려면 아래와 같이 할 수 있다.
    //여기 코드에서는 아이템 명을 바꾸는 코드지만 우선순위는 내부 리스너 먼저이기에 작동하지 않음.
    override fun onClick(view: ItemAccountBinding, position: Int) {
        view.tvAccountName.text = "Test"
    }
}
val obj2 = object: AllAccountListAdapter.OnLongClickInterface {
    override fun onLongClick(view: View, position: Int) {
        //Toast.makeText(context,"롱클릭",Toast.LENGTH_SHORT).show()
    }
    override fun onLongClick(view: ItemAccountBinding, position: Int) {
        TODO("Not yet implemented")
    }
}

val itemClickInterface: AllAccountListAdapter.OnClickInterface = obj
val itemLongClickInterface: AllAccountListAdapter.OnLongClickInterface = obj2

6. Adapter 생성할 때 필요한 값 넣어주기

Adapter Class 생성자에 파라미터를 추가했기 때문에 그에 맞게 넣어주면 된다. 

//Adapter 생성자 부분에 위에서 생성한 object를 넣어주기 
val adapter =AllAccountListAdapter(requireContext(), it, itemClickInterface, itemLongClickInterface)

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유