본문 바로가기
안드로이드

[Android Studio] 어댑터에서 콜백 리스너 사용하기

by 개발_블로그 2022. 11. 19.
반응형

 

오늘은 리사이클러뷰 어댑터에서 콜백 리스너를 사용해 보려고 합니다. 

 

만약에 구조가 MainActivity - Another BottomSheetFragment - Another BottomSheetFragment 안의 리사이클러뷰가

생성되있다고 가정하고  리사이클러뷰 안의 아이템을 클릭했을 때 메인 Activity 까지 클릭 이벤트를 전달하고 싶다고 가정을 해보겠습니다.

 

일단 클릭시 사용되어야하는 이벤트 리스너 interface 를 생성해줍니다 

 

interface MainEventListener {
    fun clicked(data: Data)
}

 

그 후에 MainActivity에 interface를 implement를 합니다. 

class MainActivity : BaseActivity<ActivityMainBinding>(), MainEventListener {

    override fun clicked(data: Data) {
   		//리사이클러뷰 어댑터에서 클릭시에 사용될 이벤트를 넣는 곳 
    }
    
}

 

이제 Another BottomSheetFragment 를 생성해줍니다. Layout은 생략하겠습니다

 

class Fragment(
    private val eventListener: MainEventListener
) : BaseBottomSheetDialog<FragmentMainBottomBinding>() {
    override fun getLayoutRes(): Int = R.layout.fragment_main_bottom

    override fun onBindView() = with(binding) {
  
    }
}

 

이제 리사이클러뷰 Adapter를 생성해보겠습니다. 아이템 레이아웃생성과 데이터도 리사이클러뷰에 넣어줬다고 가정을 해보겠습니다. 

파라미터로 이벤트리스너를 넣어줍니다. 

callback: (type : Data) 에서 타입 객체에 Data를 넣어주겠다는 뜻입니다. String ,Int 필요한 타입으로 설정하면 됩니다.

 

class Adapter(
    private val callback: (type: Data) -> Unit // 파라미터로 콜백을 넣어준다. 
) : ListAdapter<Data, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
    companion object {
        private val DIFF_CALLBACK =
            BaseDiffCallback<Data>({ old, new -> old == new })
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RecyclerView.ViewHolder {
        Item.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        ).let {
            return ViewHolder(callback) //뷰 홀더에서도 콜백을 넣어준다. 
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
        (holder as ViewHolder).bind(getItem(position))


    class ViewHolder(
        private val binding: Item,
        private val callback: (type: Data) -> Unit 
    ) : RecyclerView.ViewHolder(binding.root) {

        fun bind(item: Data) {
         
                root.setOnClickListener {
                     callback(item)  //클릭시에 콜백 함수를 실행하도록 설정한다. 
                }
            }
        }
    }
}

 

이제 리사이클러뷰 아이템 클릭시에 Another BottomSheetFragment 로 함수가 실행이 됩니다. 

 

다시  Another BottomSheetFragment로 돌아와서 어댑터를 초기화 하겠습니다. 

class Fragment(
    private val eventListener: MainEventListener
) : BaseBottomSheetDialog<FragmentMainBottomBinding>() {
    override fun getLayoutRes(): Int = R.layout.fragment_main_bottom

    override fun onBindView() = with(binding) {
        initRecyclerView()
    }

    private fun initRecyclerView() = with(binding) {
        val adapter = Adapter() { // 이 부분이 중요
                eventListener.clicked(it)
                dismiss()
            }.apply {
                this.submitList(list)
            }
        recyclerView.adapter = Adapter
    }
}

 

위의 Adapter() 옆에 { } 중괄호 부분이 보이실 겁니다. 그 부분 안에 MainActivity에서 상속받은 이벤트리스너 함수를 넣어줍니다. 

it은 람다식으로 아이템 클릭시에 넣어준 Data 입니다. 

root.setOnClickListener {
    callback(item)
}

 

이렇게 설정을 해주셨다면 마지막으로  MainActivity 에서  Another BottomSheetFragment 를 초기화 해주고 이벤트가 일어나게 해보겠습니다. 

 

class MainActivity : BaseActivity<ActivityMainBinding>(), MainEventListener {
  
   private val BottomSheetDialog by lazy {
         Fragment(this@MainActivity)
    }

    override fun clicked(data: Data) {
    	//리사이클러뷰 어댑터에서 클릭시에 사용될 이벤트를 넣는 곳 
    }
    
}

 

 

이상 콜백리스너 사용하기였습니다. 

이 콜백 리스너를 파라미터로 잘 사용할 수 있으면 복잡한 로직을 좀 더 쉽게 풀을수 있을것 같습니다. 

반응형