버그 잡이

[Kotlin] 안드로이드 recyclerView 클릭 리스너 달기 #onItemclickListener 본문

안드로이드

[Kotlin] 안드로이드 recyclerView 클릭 리스너 달기 #onItemclickListener

버그잡이 2020. 4. 28. 16:42

 

recyclerView에서의 클릭 리스너 구현은 매번 까먹는다. 이 기회에 정리해보자.

 

 

 

1. 추상메서드

 

- 클릭시 caller에게 클릭되었다는 사실을 알려줄 종(bell)이 바로 이 추상메서드이다.

 

val onItemClickListener : ((Int)->Unit)? = null

 

- 람다식으로 구현했다. int 타입 하나를 매개변수로 받고 반환값이 없는 람다 함수이다.

  *Unit은 java의 void와 같은 개념이다(return 값이 없음)

 

 

 

 

2. Item 클릭시 추상메서드 전달

 

- 이제 추상메서드를 사용해보자.

- item 클릭시 추상 메서드를 실행함으로써 이벤트를 처리한다.

- position만 넘겨주고 구체적인 동작은 Caller인 Activity에서 정의한다.

 

item.setOnClickListener{
    var position: Int = item.tag as Int
    onItemClickListener?.invoke(position)
}

 

 

*이때 해당 Item의 position을 넘겨줘야하는데 이를 위해서 binding 할때 tag를 지정해줘야한다.

 

override fun onBindViewHolder(holder: MovieListViewHolder, position: Int) {
   
    holder.containerView.tag = getItemId(position)
}
 
 override fun getItemId(position: Int): Long { 
        return position.toLong() 
    }

- getItemId는 아이템별로 Id를 부여해주는 adapter의 자체적인 추상메서드이다. 반환값이 Long으로 지정되어있다.

- onBindViewHolder에서 getItemId를 활용해 tag를 설정한다.

 

 

 

 

 

3. 추상메서드 내용 구체화

 

- caller인 Activity에서 클릭시 구현될 동작을 작성해주면 된다.

 movieListAdapter.onItemClickListener = {
 
 	//원하는 내용 작성
            
        }

 

 

 

------------------------------------------------------2020.05.04(월) 수정 -----------------------------------------------

 

 

adapter에서 position은 tag로 받았었는데 이는 불필요한 코드였다.

 

position은 viewholder에서 getAdapterPostion으로 받을 수 있기 때문에 이를 활용하는 것이 계산도 적게 들고 깔끔한 코드이다.

 

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieListViewHolder {
        context = parent.context

        val item = LayoutInflater.from(parent.context).inflate(R.layout.item_movie, parent, false)

        val movieListViewHolder = MovieListViewHolder(item)

        item.setOnClickListener {
            var position = movieListViewHolder.adapterPosition
            onItemClickListener?.invoke(position)
        }

        return movieListViewHolder
    }

 

 

 

*onCreateViewHolder  vs  onBindViewHolder 어디에 listener를 달아줘야할까?

 

리사이클러뷰는 뷰홀더를 재활용하는 구조이기 때문에 뷰홀더 create는 한 화면에 들어갈 만큼만 만들어지지만 bind는 그 뷰홀더에 계속해서 새로운 데이터를 입히는 과정으로 스크롤로 자료가 변경될때마다 이루어진다.

 

onBindViewHolder는 뷰홀더에 데이터가 바인딩 될때마다 호출되는 method로 불필요한 listener 재생성이 이루어진다.

반면 onCreateViewholder는 뷰홀더를 만들때만 listener를 달아주면 되어 보다 효율적이다.

 

 

 

 

반응형
Comments