2019.09.20
개발하면서 경험했던 것을 정리한 포스트입니다. 오류 지적이나 제안 언제든지 환영합니다.
안녕하세요. 이번 포스팅에서는 ListView 혹은 RecyclerView에서 Adapter를 매번 만들어 써야 하는 귀찮고 수고스러운 부분을 Base를 두어 공통으로 처리하는 방법을 알아보겠습니다.
(먼저 ListView를 알아보고 다음 이어진 포스팅에서 RecyclerView에 대해 알아보도록 하겠습니다.)
우선 기존 ListView를 작성하는 방법에 대해 알아보고 다음 ViewHolder패턴을 활용한 Base처리 방법으로 넘어가겠습니다.
ListView Adapter
기존 ListView는 List가 여러 개일 때 아래와 같이 Adapter를 Custom ListViewAdapter1, Custom ListViewAdapter2, Custom ListViewAdapter3.... 이렇게 만들었습니다. (너무너무 귀찮..)
1
이제 이런 Adapter를 Base로 처리하기 전에 위에서 본 Adapter의 성능에는 문제가 있습니다.
getView()는 새로운 아이템을 추가할 때마다 호출되는데 만약 아이템이 100만 개다? 그러면 100만 번 호출하게 되는 거죠..
inflate에 대한 비용이 크기 때문에 스크롤을 내릴 때마다 View를 inflate 하게 되므로 스크롤이 부드럽지 않고 각 아이템의 데이터가 클경우(이미지...)에는 스크롤이 끊기는 현상이 발생합니다.
2
위의 Adapter코드를 아래와 같이 수정해줍니다.
convertView가 null이 아닌 경우에는 기존에 있는 View를 재활용하도록 하게만듭니다. 이 방법은 ListView가 화면에 보이는 개수만 View에 inflate 하게 되며 나머지 아이템은 View를 재활용하여 성능을 향상 시킬수 있습니다. 즉 100만개의 아이템이 있어도 화면에 보이는 아이템이 30개이면 30번의 inflate만 필요하게 됩니다.
하지만 여기서도 불필요한 작업이 포함되어있습니다.
convertView?.tv_item?.text = items[position]
View는 재활용을 하여 사용하는데 정작 View가 가지고 있는 TextView는 findViewById()를 통해 매번 정보를 가져오고 있습니다.(코틀린 extension을 사용하였지만 bytecode로 디컴파일하여 변경하면 findViewById()로 매번 가져오는 것을 확인할 수 있습니다.)
kotlin code를 java code로 디컴파일한 코드
그럼 이제 ViewHolder 패턴을 알아보고 Base를 만들어 공통으로 처리해보도록 하겠습니다.
ViewHolder 패턴
ViewHolder패턴은 위에서 보신 바와 같이 정작 View는 재활용하여 사용하고 있지만 View가 가지는 TextView에 대해서는 매번 findViewById()를 통해 가져옵니다. 100만 개의 아이템에 표시할 정보가 각 5개가 있다고 한다면 500만 번의 findViewById()를 하게 되므로 성능상 문제가 있습니다. 따라서 findViewById()의 비용을 줄이기 위해 사용됩니다.
3
위의 코드에 ViewHolder패턴을 적용하여 수정합니다.
위와 같이 ViewHolder패턴을 사용하여 View가 null일 때 view의 tag에 viewholder object를 넣고 이미 생성된 view라면 저장된 tag의 viewholder object를 꺼내와 사용함으로써 성능을 향상 시킬수 있습니다.
다음은 Adapter를 공통으로 처리할 수 있게 base adapter를 만들어 보겠습니다.
우선 현재까지의 adapter에서는 여러 개의 리스트가 있다면
name, address가 포함된 viewholder를 표시하는 adapter1
title, author가 포함된 viewholder를 표시하는 adapter2....
이처럼 여러 데이터 형태를 가지는 viewholder에 대해 각각의 adapter를 만들어야 했습니다.
이제 우리는 하나의 adapter만 만들어두고 각각 들어갈 viewholder만 정의하여 사용하고 싶습니다.
Base ListView Adapter
4
우선 아래와 같이 코드를 수정해줍니다.
이제 우리는 base Adapter와 base ViewHolder만 만들어두고 custom viewholer를 생성하여 Listview를 구현할 수 있습니다. 위의 코드에서 변경된 점은
1. Generic으로 List타입 정의
2. Generic으로 ViewHolder 타입 정의
3. BaseViewHolder의 추상화 및 상속 구현
이렇게 구현해줌으로써 여러개의 ListView를 사용할때 각 ListView에 맞는 데이터 ViewHolder만 지정해주어 구현할 수 있게되었습니다.
다음 포스팅에서는 Base RecyclerView Adapter를 만들어 공통으로 처리하는 방법을 알아보겠습니다.
감사합니다.
❤️
Love YourSelf
'Android' 카테고리의 다른 글
[Android] MediaController dispatchKeyEvent not called (0) | 2019.10.22 |
---|---|
[Android] Gradle Dependency Conflict문제 해결하기 (0) | 2019.10.18 |
[Android] 빌드에러 : Execution failed for task ':app:packageDebug'. (0) | 2019.09.06 |
[Android] 키보드 올리기 / 숨기기 (android keyboard show / hide) (0) | 2019.08.26 |
[Android] Android Studio Live Template 알아두기#2 (0) | 2019.08.13 |