Intro
- 어제부터 리사이클러뷰에대해 알아가는 시간을 가지고있다. 리사이클러뷰는 리스트뷰의 단점을 보완하고 개발자에게 편의성을 제공하기위해 만들어졌다고 알고있다.
- 리스트뷰는 굉장히 굉장히 오래전부터 안드로이드에 있었다고한다. 리사이클러뷰를 구현하고 공부하다보니 리사이클러뷰를 이해하려면 리스트뷰에대한 이해가 선행되어야겠다는 생각이들었다. 그리고 리스트뷰의 성능이 얼마나 안좋은지도 눈으로 보고싶었다.
ListView 구현해보기
- 구현방법은 리사이클러뷰와 당연히 비슷하다. 순서는 아래와 같이 진행된다.
- xml에 리스트뷰 선언하기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/lv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- item 선언하기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="10dp"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_listview_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="todo" />
</androidx.constraintlayout.widget.ConstraintLayout>
- item에 넣을 데이터 정의(난 간단히 테스트해보고싶어 생략했다.)
- adapter 구현
package bootcamp.sparta.listviews
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
class ListviewAdapter : BaseAdapter() {
override fun getCount(): Int {
return 1000
}
override fun getItem(p0: Int): Any {
return p0
}
override fun getItemId(p0: Int): Long {
return 0
}
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val view = LayoutInflater.from(p2?.context).inflate(R.layout.item_listview_main, null)
view.findViewById<TextView>(R.id.tv_listview_title).text = "toDo"
return view
}
}
- 적용
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val listview = findViewById<ListView>(R.id.lv_main)
val adapter = ListviewAdapter()
listview.adapter = adapter
}
}
- 실행결과 묘하게 스크롤에서 끊김이 발생했다. 프로파일러도 켜보았다. 그리고 정확하지는 않더라도 측정을 위해 동일한 설정으로 리사이클러뷰도 테스트를 진행해봤다.
- 둘 모두 단순 TextView 하나에 아이템개수 1000개로 진행해봤다.
Listview
RecyclerView
테스트결과
- 자료가 얼마없어서 눈에잘보이지는않지만 두 영상을 비교해보면 확실히 리사이클러뷰의 스크롤이 더 부드러운것을 알 수 있다. 그리고 이것은 item정보가 많으면 많을수록 더욱 크게 차이가 날것이다.
- 성능을보면 왜그런지 이유를 알 수 있다. 리사이클러뷰는 성능의 미동이없다. 반면 리스트뷰는 램이 미친듯이 올라가 1기가를 찍는다... 그래서 중간에 앱이 갑자기 종료되는 상황도있었다.
Why?
- 전에 포스팅올렸던것처럼 리사이클러뷰는 item을 viewHolder 패턴을 사용해 재활용하는반면 리스트뷰는 재활용을 하지 않고 구현했다(물론 리스트뷰에서도 성능이슈때문에 ViewHolder 패턴을 적용하는게 구현시 권고사항이라고한다. 문제는 이게 권고사항이라 개발자가 구현하지않을 수도 있다는것이다. 그러면 위와같은 성능문제가 발생한다.)
Outro
- 생각보다 성능차이가 엄청났다. 이게 단순 ViewHolder 패턴으로 인함인지 아니면 뭔가 더 차이가나는지까지는 모르겠다.
- ListView에 여러 실험을 해가며 RecyclerView를 이해해보고자한다. RecyclerView의 동작원리를 파악하는 그날까지 아자아자! 끗!