[내일배움캠프] 캠프 19주차 - 3/21(목) #RecyclerView #payload

0
post-thumbnail
post-custom-banner

📝TIL

RecyclerView Drag & Drop 시, 순서 변경된 항목 binding하기

📌참고자료

  • RecyclerView Drag & Drop으로 항목 순서 변경은 구현하였으나, 항목의 순서를 나타내는 TextView가 변경된 순서를 반영하지 않는다
    -> 어댑터에게 항목 순서 변경을 알리기 위해 사용하는 notifyItemMoved 함수는 structural change event가 일어났음을 알림
    -> 어댑터는 ViewHolder의 순서를 바꿀 뿐 새로 binding하지 않는다
  • 어댑터가 ViewHolder를 다시 binding하도록 하기 위해 item change event를 알리는 함수를 함께 사용해야한다
    ex. notifyDataSetChanged, notifyItemChanged, notifyItemRangeChanged
    -> 우리는 drag&drop 시작 위치~끝 위치에 있는 항목들만 다시 binding하면 되므로 notifyItemRangeChanged 함수를 사용하자

  • notifyItemRangeChanged(positionStart: Int, itemCount: Int) 함수 사용

routeAdapter.apply{
    notifyItemMoved(fromPosition,toPosition)
    notifyItemRangeChanged(min(fromPosition, toPosition), abs(fromPosition - toPosition) +1)
}
  • 실행 화면
    -> 항목의 순서가 변경될 때, 항목의 순서를 나타내는 TextView만 다시 binding 되면 좋겠지만, ViewHolder 전체가 다시 binding 된다.
    -> 이를 해결하기 위해 사용하는 것이 payload다!!

payload

  • RouteAdapter에서 onBindViewHolder() 오버라이드
    override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
        if (payloads.isEmpty())
            super.onBindViewHolder(holder, position, payloads)
        else
            holder.positionTextView.text = (position + 1).toString() 
    }
  • notifyItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) 함수 사용
routeAdapter.apply{
    notifyItemMoved(fromPosition,toPosition)
    notifyItemRangeChanged(min(fromPosition, toPosition), abs(fromPosition - toPosition) +1, Any())
}
  • 실행 화면

profile
Be able to be vulnerable, in search of truth
post-custom-banner

0개의 댓글