티스토리 뷰

Android App Coding

뷰 홀더 View Holder

IT Knowledge Share 2021. 7. 9. 14:12
반응형

리스트뷰에서 자주 사용되는 뷰 홀더에 대해서 확인합니다.

 

어댑터의 전체적인 뷰를 그려주는 getView 메소드에서 뷰 홀더를 사용하여 뷰를 나타낼 수 있습니다. 뷰 홀더를 사용하는 이유는, findViewById로 필요한 뷰를 찾는 경우, 찾아야 하는 뷰가 많을 수록 그만큼 리소스가 많이 필요하고, 성능에 영향을 줄 수 있기 때문이라고 합니다.

 

우선 뷰홀더 클래스를 생성합니다. 앞으로는 뷰홀더에 사용할 뷰를 미리 담아놓고, 필요 시 불러와서 계속 써먹게 되는 원리입니다. null 값이 할당될 수 있도록 TextView? 타입으로 선언합니다.

class ViewHolder{
    var guestName: TextView? = null
    var waiting: TextView? = null
}

다음은 어댑터 클래스의 getView 메소드를 다음과 같이 코딩해줍니다.

반응형
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {

        val view: View
        val holder: ViewHolder
    
        if (convertView == null) {
        
            view = layoutInflater.inflate(R.layout.item_view, null)
            holder = ViewHolder()
           
            //findViewById로 뷰 찾은 후에 홀더에 넣기
            holder.guestName = view.findViewById(R.id.guest_name)
            holder.waiting = view.findViewById(R.id.waiting)

            //찾을수 있도록 tag 달기
            view.tag = holder

        } else {
        
            holder = convertView.tag as ViewHolder
            view = convertView
        }

        holder.guestName?.setText(waitForList.get(position).guest_number)
        holder.waiting?.setText(waitForList.get(position).waiting_number)

        return view
}

우선 view와 ViewHolder를 선언하고, if~else 문으로 구성된 부분을 확인하면, 만약 convertView가 없다면(즉 null 값이라면) 뷰를 찾은 후에 홀더에 담아두고, 나중에 필요할 때 태그(tag)로 찾아서 해당 뷰를 써먹으면 됩니다. convertView가 있는 경우는 이미 태그해둔 것을 찾아오면 됩니다. 그리고 setText 메소드를 통해서 찾은 뷰를 넣어준 뒤 view를 리턴해주는 방식입니다.

 

좀 더 자세히 살펴보도록 합니다.

if (convertView == null) {

            view = layoutInflater.inflate(R.layout.item_view, null)
            holder = ViewHolder()
           
            holder.guestName = view.findViewById(R.id.guest_name)
            holder.waiting = view.findViewById(R.id.waiting)

            view.tag = holder

} else {
            holder = convertView.tag as ViewHolder
            view = convertView
}

우선 위의 코드에서 convertView는 재활용하게 될 뷰를 의미하며, 컨버트뷰가 없다면, 뷰를 만들어 놓고 태그해둡니다. 

컨버트뷰가 null 값인 경우, findViewById로 원하는 뷰를 찾아와서 홀더에 담게 됩니다. 이후 나중에 찾을 수 있도록 태그합니다.

 

만약, else 문처럼, 컨버트뷰가 있다면, 이미 태그했던 것을 그대로 가져와서 'as ViewHolder'로 캐스팅 한 뒤에 홀더에 담습니다. 그리고 해당 컨버트뷰를 view로 선언해줍니다.

 

아래 코드는 if~else 문 이후의 코드입니다.

holder.guestName?.setText(waitForList.get(position).guest_number)
holder.waiting?.setText(waitForList.get(position).waiting_number)

return view

 

컨버트뷰를 setText 부분에 할당시켜서 실제 view를 리턴해줌으로써 뷰가 그려지게 됩니다. 처음에 뷰홀더 클래스에서 TextView? 타입이었기에, 널값이 아니면 setText 해줄 수 있도록, guestName?, waiting? 이렇게 처리해줍니다.

반응형

'Android App Coding' 카테고리의 다른 글

탭레이아웃 TabLayout  (0) 2021.07.09
리사이클러뷰 RecyclerView  (0) 2021.07.09
토스트 메시지 Toast  (0) 2021.07.09
리스트뷰와 어댑터 ListView & Adapter  (0) 2021.07.09
애드뷰 Addview  (0) 2021.07.09
댓글