본문 바로가기

안드로이드

[안드로이드] RecyclerView 여러 개의 ViewType 활용하기

개요

카톡 채팅방은 RecyclerView의 구조로 이루어져 있다. 하지만 내부 아이템을 보면 좌측에는 상대방의 채팅, 우측에는 자신의 채팅이 출력된다. 각 채팅의 뷰는 비슷한 모양이긴 하지만 왼쪽, 좌측으로 치우쳐져 있다는 점에서 서로 다르다. 이때, 사용하는게 ViewType을 이용한 View 구분이다.

 

구현 과정

0. 채팅 데이터 클래스를 정의한다.

data class ChatItem(
    val sender: String,
    val message: String,
    val count: Int,
    val viewType: Int = 0
)

 

1. 다음으로 사용하고 싶은 아이템의 레이아웃을 생성한다.

다른 상대방들의 채팅
내가 작성한 채팅

2. 리사이클러뷰 어답터에 getItemViewType을 정의해준다.

  여기서 이 함수의 반환 결과로 아이템의 ViewType이 반환되는데 이는 onCreateViewholder의 매개변수 viewType으로 전달된다. 

override fun getItemViewType(position: Int): Int {
        return if(list.isNotEmpty())
            list[position].viewType
        else
            super.getItemViewType(position)
    }

 

3. 그 이후 레이아웃에 해당하는 적절한 ViewHolder를 정의해준 뒤, 다음과 같이 코드를 작성한다.

  반환받은 viewType에 따라 서로 다른 뷰홀더를 리턴해주고 bind에는 넘어온 뷰홀더의 객체에 따라 서로 다른 bind를 진행한다.

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        when(viewType){
            MY_CHAT -> {
                val view = LayoutInflater.from(context).inflate(R.layout.item_my_chat, parent, false)
                return MyChatViewHolder(view)
            }
            OTHER_CHAT ->{
                val view = LayoutInflater.from(context).inflate(R.layout.item_chat, parent, false)
                return OtherChatViewHolder(view)
            }
            else ->{//cannot reach this
                val view = LayoutInflater.from(context).inflate(R.layout.item_chat, parent, false)
                return OtherChatViewHolder(view)
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if(holder is MyChatViewHolder){
            holder.bind(list[position])
        }else if(holder is OtherChatViewHolder){
            holder.bind(list[position])
        }
    }