내가 프로젝트에서 RecyclerView 를 사용하기 위해 공부를 했던 내용을 적어본다.(프로젝트 후 리사이클러뷰를 공부할 당시에 기록한 것을 토대로 작성한 글이다.)
RecyclerView를 알기전에 같은 기능이지만 전에 나온 기술인 ListView와 비교를 해봄으로써 RecyclerView를 선호하고 계속해서 쓰는이유, 장점, 대략적인 사용 방법에 대해 알아보겠다.
◼️ RecyclerView vs ListView ◼️
간단히 말해서 ListView의 단점을 보완하기 위해 나옴
>> ListView는 리스트 항목이 갱신될 때마다, 매번 아이템 뷰를 새로 구성해야 함 → 성능 低
ListView의 단점인 리스트 갱신때마다 아이템 뷰를 새로 구성하는 방식이 아닌 효율적인 방법은 없을까?
◼️ 데이터를 화면에 보여주는 좋은 방법은 무엇일까? ◼️
데이터를 화면에 보여주는 좋은 방법을 다른 말로 한다면 많은 데이터를 화면에 처리하려면 어떻게 하면 효율적인가를 생각해본다.
근본적으로 데이터를 화면에 보여주기 위해서는 메모리에 올라가 있으면 된다. 방법 2가지는
- 그때 그때 마다 메모리에 view 그리기 -> 스크롤 할 때마다 딜레이 생김
- 모든 데이터를 메모리에 미리 view형식으로 올린다 -> 메모리 유출 발생
➡️ 이러한 문제들을 해결하기 위해서 RecyclerView 가 나타나게 되었다.
즉, 어떻게 해결을 하였나면.
화면을 아래로 스크롤하여 item 이 screen 밖으로 벗어낫을 때, 리사이클러뷰는 해당 item 의 view를 파괴하지 않는다. 대신, scroll 후에 새로운 item 을 화면에 표시할 때 view를 재사용하게 된다. 이것은 app의 반응과, 전력소비를 줄이는데 크게 기여를 하였다.
정리를 해보자면 리사이클러뷰(RecyclerView)는"사용자가 관리하는 많은 수의 데이터 집합(Data Set)을 개별 아이템 단위로 구성하여 화면에 출력하는 뷰그룹(ViewGroup)이며, 한 화면에 표시되기 힘든 많은 수의 데이터를 스크롤 가능한 리스트로 표시해주는 위젯"이다.
◼️ 리사이클러뷰의 방식 ◼️
- 리사이클러뷰는 처음 데이터를 표현할 때에만 뷰홀더에 뷰를 생성한다.(Visbile Screen에 보여줄 갯수 + Smooth한 스크롤을 위한 추가갯수)
- 리사이클러뷰는 미리 생성한 뷰들을 큐 또는 recycling bin에 넣어 놓는다.
- 스크롤시에는 미리 생성한 뷰들을 큐에서 빼서 데이터를 채워넣어서 뷰를 리사이클러뷰에 표시한다.(Bind !)
- 스크롤을 통해 지나간 뷰(아이템)들은 재사용을 위해서 다시 큐에 넣어 놓는다.
➡️ 위와 같은 방식의 반복을 통해서 재사용을 통해서 효율을 극대화 시키는것이 리사이클러뷰의 방식이다.
◼️ 리사이클러뷰의 구성요소 ◼️
◼️ 1. Adapter ◼️
Adapter : 간단히 사용자의 데이터 리스트로 부터 아이템뷰를 만드는 역할입니다. 새로운 뷰의 추가를 위한 어댑터, 데이터 목록을 아이템 단위의 뷰로 구성하여 화면에 표시하기 위해 사용된다.
- Adapter는 데이터를 가져와서 뷰에 적용시킨다.
- Adapter는 리사이클러뷰에게 뷰홀더를 전달시킨다.
리사이클러 뷰의 adapter를 정의하게 되면 아래 세 가지의 key method 를 override 해야한다.
- *onCreateViewHolder()
이 메서드는 리사이클러뷰에서 새로운 viewHolder를 만들어야할 때 항상 호출된다. 이 메서드는 ViewHolder 객체와 연결할 view 를 create 하고 initailize 하는 역할을 한다. 하지만, view 에 들어갈 내용 (data)는 채워져있지 않은 상태이다. - *onBindViewHolder()
이 메서드는 ViewHolder 객체와 표시될 data를 연결하는 역할을 한다. 이 메서드에서는 리스트에 출력할 data를 불러오고, view holder의 layout에 data를 채운다. - *getItemCount()
이 메서드를 사용하면 리사이클러뷰에 사용되는 data의 size를 얻을 수 있다.
◼️ 2. ViewHoler ◼️
◼️ ViewHolder : 화면에 표시될 아이템뷰를 저장하는 객체이다. 어댑터에 의해 관리되고 필요에 따라 어댑터에서 생성됩니다. Adapter를 통해 만들어진 각 아이템 뷰는 "뷰홀더(ViewHolder)"객체에 저장되어 화면에 표시되고, 필요에 따라 생성 또는 재활용(Recycle)된다.
- 실제 아이템의 레퍼런스를 가지고 있음. 또한 뷰에 새로운 데이터를 넣어 업데이트할때 캐시로 사용함.
- findviewbyid를 레이아웃에 뷰가 추가될떄가 아닌 뷰가 생성될떄만 호출되게 최소화시킬 수 있음.
(뷰홀더 사용이 중요한 이유 : 추가할 데이터나 이미지를 포함하는 뷰를 캐쉬하기 떄문에 계속 어뎁터로부터 findeviewbyid를 호출하는 것은 비싼작업이기 떄문에 비효율적이다. 특히 계층적인 뷰 구조를 가질때는 더욱 비효율적이다. 그래서 뷰홀더에 뷰전체를 캐쉬시키는것이 최선이다.)
◼️ 3. LayoutManager ◼️
◼️ LayoutManager : 리사이클러뷰에게 뷰를 어떻게 보여줄지 말해준다.
- LinearLayoutManager : 수직(vertical)또는 수평(horizontal) 방향으로 아이템뷰 배치
- GridLayoutManager : 비율이 같은 격자(Grid) 형태로 배치
- StaggeredGridLayoutManager : 엇갈린(Staggered) 격자(Grid)형태로 배치
◼️ 리사이클러뷰 작동 원리 ◼️
- 리사이클러뷰에 들어가는 리스트의 각 element 는 view holder 라는 객체 에 의해 정의된다. view holder가 created 되었을 때에는 어떤 데이터도 들어가있지 않은 상태이다. 이 후에는 view holder 객체에 data를 bind 하게 된다.
- 리사이클러뷰에서 view holder 를 만들고 data를 view 에 bind하는 과정은 adapter 에서 이뤄진다.
- layout manager 를 사용하면 리스트의 각 element를 어떤 방식으로 정돈해서 보여줄 것인지 정할 수 있다. (vertical, horizontal, gird, etc..)
◼️리사이클러뷰의 대략적인 사용 방법 ◼️
1. 사용할 Activity XML에 RecyclerView 추가
2. RecyclerView 아이템에 표시될 View 레이아웃 추가
( → 아이템 View를 위한 레이아웃 XML 작성 )
3. Adapter 구현
( → RecyclerView.Adapter상속하여 구현 )
리사이클러뷰에서는 반드시 개발자가 어댑터를 직접 구현해야 합니다. 그리고 이 때 새로 만드는 어댑터는 RecyclerView.Adapter를 상속하여 구현해야 한다.
-RecyclerView.Adapter를 상속받아 새로운 어댑터를 만들 때, 오버라이드가 필요한 메서드-
onCreateViewHolder(ViewGroup parent, int viewType) viewType 형태의 아이템 뷰를 위한 뷰홀더 객체 생성.
nBindViewHolder(ViewHolder holder, int position) position에 해당하는 데이터를 뷰홀더의 아이템뷰에 표시.
getItemCount() 전체 아이템 갯수 리턴.
4. Adapter , 레이아웃매니저 지정
( → setAdapter(), setLayoutManger() )