ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Recycler View] Recycler View : adapter
    Android📱 2022. 3. 29. 15:41

    Recycler View 시리즈 첫 번째

    안드로이드를 사용하다 보면

    참고. 안드로이드 샘플 코드

    이렇게 항목을 보여주는 창들을 만날 때가 있다.

    이런 창은 모바일에서 굉장히 많이 사용되는 형태 중에 하나인데

    이런 목록 창은 어떻게 만드는 걸까?

    그에 대한 해답이 Recycler View이다.

    ListView vs Recycler View

    예전에는 위 형태의 창을 만들 때 List View라는 것을 사용하였다.

    하지만 List View는 세로로 스크롤하는 형태만 구현이 가능했고, 커스텀이 힘들었다.

    또한 Lsit View는 뷰 홀더를 구현하지 않아도 됐지만, 아이템을 생성할 때마다 뷰 바인딩을 해주어야 해서 성능 저하도 발생시켰다.

    위 그림처럼 리스트 뷰로 만든 뷰는 스크롤을 하면 getView가 찍히는 것을 볼 수 있다.

    반면 Recycler View는 onCreateViewHolder가 전부 실행이 되면 그 뒤로는 onBindViewHolder만 뜨는 것을 볼 수 있다.

    이런 이유는 Recycler View는 이름처럼 뷰를 재사용하기 때문이다.

    List View의 Adapter 부분을 보면 List View는

    
    class ListAdapter(private val context: Context, private val studentList: MutableList<Students>) : BaseAdapter() {
        override fun getCount() = studentList.size
    
        override fun getItem(position: Int) = studentList[position]
    
        override fun getItemId(p0: Int) = 0L
    
        override fun getView(position: Int, view: View?, parent: ViewGroup?): View {
            val view: View = LayoutInflater.from(context).inflate(R.layout.list_view_item, null)
    
            val dogPhoto = view.findViewById<ImageView>(R.id.image)
            val dogBreed = view.findViewById<TextView>(R.id.name)
            val dogAge = view.findViewById<TextView>(R.id.age)
            val dogGender = view.findViewById<TextView>(R.id.gender)
    
            val student = studentList[position]
            val resourceId = context.resources.getIdentifier(student.photo, "drawable", context.packageName)
            dogPhoto.setImageResource(resourceId)
            dogBreed.text = student.name
            dogAge.text = student.age.toString()
            dogGender.text = student.gender
    
            Log.d("ListAdapter", "getView")
    
            return view
        }
    
    }

    findViewById를 이용해서 getView를 할 때 매번 띄워야 할 아이템 뷰를 찾지만

    Recycler View는

    class RecyclerAdapter(val context: Context, val students: List<Students>) : RecyclerView.Adapter<RecyclerAdapter.Holder>() {
    
        inner class Holder(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {
            val photo = itemView?.findViewById<ImageView>(R.id.image)
            val name = itemView?.findViewById<TextView>(R.id.name)
            val age = itemView?.findViewById<TextView>(R.id.age)
            val gender = itemView?.findViewById<TextView>(R.id.gender)
    
            fun bind (students: Students, context: Context) {
    
                if (students.photo != "") {
                    val resourceId = context.resources.getIdentifier(students.photo, "drawable", context.packageName)
                    photo?.setImageResource(resourceId)
                } else {
                    photo?.setImageResource(R.mipmap.ic_launcher)
                }
    
                name?.text = students.name
                age?.text = students.age.toString()
                gender?.text = students.gender
    
                Log.d("RecyclerAdapter", "bind")
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
            val view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, parent, false)
            Log.d("RecyclerAdapter", "onCreateViewHolder")
            return Holder(view)
        }
    
        override fun onBindViewHolder(holder: Holder, position: Int) {
            Log.d("RecyclerAdapter", "onBindViewHolder")
            holder.bind(students[position], context)
        }
    
        override fun getItemCount() = students.size
    }

    Holder에서 한번 찾고 나서 bind를 통해 뷰에 아이템 정보를 넣어줄 뿐 매번 뷰를 찾아오지는 않는다.

    만약 스크롤을 빠르게 움직이거나, 데이터가 매우 많다면 버벅거림이 생길 것이다.
    또 Recycler View는 LayoutManager를 통해서 형태도 조절이 가능해서
    List View 보다는 Recycler View가 많이 사용되고 권장되고 있다.

    Adapter

    위 예시 코드를 보면 Adapter가 나온다.

    Adapter는 무엇일까?

    Adapter란?

    RecyclerView.Adapter가 하는 일은 실제로 우리가 아는 어뎁터와 비슷하다.

    기기를 연결할 수 있게 케이블을 바꾸거나 하는 어뎁터처럼 RecyclerView.Adapter도 데이터를 RecyclerView에서 볼 수 있도록 바인딩해주는 역할을 한다.

    한마디로 받은 데이터를 화면에 어떻게 보여줄지를 정해주는 부분이라고 생각하면 된다.

    List View의 Adapter는 BaseAdapter를 이용해서 만들지만 Recycler View의 Adapter는 RecyclerView.Adapter를 상속받아서 구현을 하게 된다. (List Adapter도 가능)

    Recycler View를 사용할 Activity에서 xml에 Recycler View를 만들어주고, Adapter를 참조해서 데이터 리스트를 넘겨주고 Recycler View에 연결해주면 Adapter를 사용할 수 있게 된다.

    RecyclerView.Adapter에는 onCreateViewHolder, onBindViewHolder, getItemCount이 세 개의 메서드가 있고 이를 Adapter에서 오버라이드 해서 구현을 하게 된다.

    그러면 Adapter에서 onCreateViewHolder가 아이템 뷰를 inflat 해주고 onBindViewHolder는 새로 보일 데이터의 인덱스와 사라진 레이아웃을 이용해서 새로운 아이템을 화면에 보이게 해 준다.

    그래서 위아래 버퍼를 포함한 개수만큼만 onCreateViewHolder로 뷰를 생성하고 그 후에는 onBindViewHolder만 사용해서 데이터만 변경하게 되는 것이다!

    소스 코드

    'Android📱' 카테고리의 다른 글

    ktlint를 사용해보자!  (0) 2022.07.28
    [Recycler View] View Holder  (0) 2022.03.29
    [안드로이드] Back Stack???  (0) 2022.03.28
    [안드로이드] Context  (0) 2022.03.28
    [ERROR] Can't toast on a thread that has not called Looper.prepare()  (0) 2022.03.25
Designed by Tistory.