본문 바로가기
Android

[Android] Recyclerview 에 대해 알아보자!

by 너츠너츠 2022. 1. 17.

안드로이드에서 똑같은 형식의 데이터들을 관리할 때 예전에는 ListView를 사용했지만 현재는 RecyclerView를 사용합니다.

 

기본적으로 ListView와 Recyclerview은 사용 목적 및 동작 방식이 매우 유사하지만 큰 차이점으로는 ListView는 수평으로 나열하기 힘들고 커스터마이징이 힘들다는 단점이 있습니다.

 

 

RecyclerView는 이름 그대로 "재활용"한다는 뜻을 가진 View입니다. 위의 그림이 대표적인 예시라고 볼 수 있습니다. 예전에는 많은 수의 데이터를 표시하는데 똑같은 형식이더라도 매번 새로운 아이템 뷰를 구성해야했지만 RecyclerView를 사용하면 그렇지 않기에 성능적인 측면에서 개선됩니다.

 

위의 그림처럼 RecyclerView는 동작하게 됩니다. Data List에 저장되어 있는 각 position의 data들이 Adapter를 거쳐RecyclerView에 해당하는 Item View에 넣어지게 됩니다. ItemView의 방향은 Layout Manager를 통해 수직, 수평 등 원하는 방향으로 설정할 수 있습니다.

 

<Activity의 Recyclerview 설정>

binding.recyclewview.apply {
     setHasFixedSize(true)
     layoutManager = LinearLayoutManager(context)
     adapter = CustomAdapterByBinding(this@MainActivity, dataList) //binding을 활용한 adapter 구현
//   adapter = CustomAdapterByFindId(this@MainActivity, dataList) //findViewById를 활용한 adapter 구현
}
  •  layoutManager: RecycierView는 LayoutManager를 통해 정렬됨
    • LinearLayoutManager: 1차원 목록 (수직, 수평)으로 정렬
    • GridLayoutManager: 모든 항목을 2차원 그리디로 정렬 (표)
      • 세로로 정렬된 경우 행마다 높이가 다를 수 있음
      • 가로로 정렬된 경우 행마다 너비가 다를 수 있음
    • StaggeredGridLayoutManager: GridLayoutManager와 비슷하지만 행의 항목이 너비 또는 높이가 동일할 필요가 없습니다
  • adapter: 생성한 Adapter를 연결해주는 것
  • setHasFixedSize: RecyclerView의 크기 변경이 일정하다는 것을 사용자가 입력해줌으로서 항목의 높이나 너비가 변경되지 않는다고 설정해주는 것입니다. 이것을 통해 Recyclerview가 변경될 때마다 크기가 변하고 이것으로 인해 레이아웃을 다시 그리게 되는 작업을 피할 수 있도록 하여 성능 하락을 방지하는 기능을 합니다.

 

<Adapter>

1. Binding을 활용한 Adapter 구현

package jgeun.study.recyclerview.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import jgeun.study.recyclerview.databinding.ItemDataBinding
import jgeun.study.recyclerview.model.Data

/*
*  binding을 활용한 adapter 구현
*/

//context: 연결될 Activity의 요소들을 가져오기 위한 context, dataList: 보여줄 data들
class CustomAdapterByBinding(private val context: Context, private val dataList: ArrayList<Data>)
    : RecyclerView.Adapter<CustomAdapterByBinding.ViewHolder>(){

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder).
     */
    class ViewHolder(private val binding: ItemDataBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(data : Data) {
            binding.title.text = data.title
            binding.content.text = data.content
        }
    }

    // view들 생성하는 함수
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : ViewHolder {
        val binding = ItemDataBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return ViewHolder(binding)
    }

    // view의 content들에 데이터를 넣어줌.
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(dataList[position])
    }

    // item의 개수
    override fun getItemCount(): Int = dataList.size
}

2. FindViewById를 활용한 Adapter 구현

/*
*  findViewById를 활용한 adapter 구현
*/

//context: 연결될 Activity의 요소들을 가져오기 위한 context, dataList: 보여줄 data들
class CustomAdapterByFindId(private val context: Context, private val dataList: ArrayList<Data>)
    : RecyclerView.Adapter<CustomAdapterByFindId.ViewHolder>(){

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder).
     */
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
        val title: TextView
        val content: TextView

        init {
            title = view.findViewById(R.id.title)
            content = view.findViewById(R.id.content)
        }
    }

    // 새로운 view 생성
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int) : ViewHolder {
        val view = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.item_data, viewGroup, false)

        return ViewHolder(view)
    }

    // 생성된 뷰의 contents에 데이터 입력
    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        viewHolder.title.text = dataList[position].title
        viewHolder.content.text = dataList[position].content
    }

    // 뷰들의 개수
    override fun getItemCount(): Int = dataList.size
}

-  onCreateViewHolder: 뷰홀더를 생성해줍니다.

- onBindViewHolder: 뷰홀더가 재활용될 때 사용되는 메소드입니다. 데이터값을 설정해주거나 각 요소의 이벤트를 설정해줄 때 사용됩니다.

- getItemCount: 아이템 개수를 조회하여 개수만큼 보여줍니다.

 

class ViewHolder의 경우 : RecyclerView.Adapter<ListAdapter.ViewHolder>() 때문에 생성됩니다. 

ViewHolder클래스를 상속받는 Custom ViewHolder를 만들어 이를 재활용하기에 데이터 개수마다의 레이아웃 생성하던 방식을 방지하여 앱의 효율을 향상시킵니다.

반응형

댓글