Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

yourginieus

RecyclerView : 아이템 클릭이벤트 본문

Android/Android Kotlin 기초 실습 정리

RecyclerView : 아이템 클릭이벤트

EOJIN 2022. 12. 14. 01:12
  • 클릭을 수신하여 처리하는 작업은 두 개로 나뉨
    • 클릭을 듣고 수신하여 클릭된 항목 확인
    • 클릭에 액션으로 응답
  • 그렇다면 앱에 click listener를 추가할만한 좋은 장소는?
    • Fragment에서 받으면 클릭이벤트를 넣어도 클릭된 아이템이 뭔지 모름
    • RecyclerView에서 받으면 사용자가 어던 항목을 클릭했는지 정확하게 파악하기 어려움
    • The best place to get information from one clicked item is in the ViewHolder object, since it represents one list item.
  • ViewHolder는 listen for clicks에는 좋지만 handle에는 별로 안 좋음. 클릭을 다루기 좋은 장소는?
    • Adapter! 어댑터에서 click을 handle할 수 있도록 data item들을 view에 표시함
    • 그러나 구조 관점에서, adapter의 역할은 display 용으로 data를 조정하는 것이지 앱 로직을 처리하는 건 아님
    • ViewModel에서 클릭을 처리할 필요가 있음
      • ViewModel에는 클릭에 대한 응답으로 필요한 작업을 결정하기 위한 데이터 및 로직에 액세스할 수 있음

1. Click listener를 생성하여 item layout에서 trigger 함

  • 코틀린 파일 열기
  • 파일 끝의 top level에서 new listener class 생성 : SleepNightListener
  • 해당 클래스 안에 onClick() function 추가 : list item으로 표시된 view가 클릭되면 이 onClick을 호출할 것
    • layout에서 onClick 추가해줘야 됨(나중에 할 것)
  • SleepNight 타입의 nignt 매개변수 추가 : view는 어떤 항목을 표시하는지 알고 있으며, 그 정보는 click을 처리하기 위해 전달되어야 함
  • onClick이 무엇을 하는지 정의하기 위해, SleepNightListener의 생성자에서 onClickListener 콜백 인수 제공
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
   fun onClick(night: SleepNight) = clickListener(night.nightId)
}
  • xml에 클릭리스너 변수 만들고 onClick 연결
<variable
            name="clickListener"
type="com.example.android.trackmysleepquality.sleeptracker.SleepNightListener" />
android:onClick="@{() -> clickListener.onClick(sleep)}"

2. Click listener를 ViewHolder와 binding 객체에 전달

  • 어댑터의 생성자 변경 : clickListener : SleepNightListener를 받도록
  • Adapter가 ViewHolder를 binds하는 경우, 이 클릭리스너와 함께 제공해야 함
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  • onBindViewHolder()에서, holder.bind()를 업데이크하기 : click listener를 ViewHolder로 전달하도록
holder.bind(getItem(position)!!, clickListener)
  • 이 때 오류가 날텐데, 이를 수정하기 위해 clickListener의 parameter에 bind 추가하기

  • bind 안의 binding object에 클릭리스너 할당하기
binding.clickListener = clickListener
  • 토스트로 테스트
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
   Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})

아이템 클릭 처리 : ViewModel

  • SleepTrackerViewModel에서
private val _navigateToSleepDetail = MutableLiveData<Long>()
val navigateToSleepDetail
   get() = _navigateToSleepDetail
fun onSleepNightClicked(id: Long) {
   _navigateToSleepDetail.value = id
}
  • Fragment.kt 에서
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
   Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})

토스트 이걸로 바꾸기

sleepTrackerViewModel.onSleepNightClicked(nightId)

'Android > Android Kotlin 기초 실습 정리' 카테고리의 다른 글

RecyclerView : GridLayout  (0) 2022.12.14
Recyclerview 기초  (0) 2022.12.13
Create a RoomDB  (0) 2022.10.27
LiveData transformations  (0) 2022.10.27
ViewModel 및 LiveData를 통한 데이터 바인딩  (0) 2022.10.27
Comments