RecyclerView는 반복되는 동일한 형태를 갖는 수많은 리스트를 구현할 때 사용한다.
구현하기 위해서는 다음과 같은 단계가 필요하다.
layout
data class
class
class
class
xml 파일 두개가 필요하다. 하나는 아이템, 하나는 아이템이 들어갈 틀이다.
item_home_chart.xml
activity_home.xml
...
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_chart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="15dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_home_chart" />
...
layoutManager
속성에서 위와 같이 선형(LinearLayoutManager)으로 배열할지, 바둑판형(GridLayoutManager)으로 배열할지 결정한다.
listitem
속성에서 틀에 들어갈 아이템을 지정한다.
각 item에는 cover image, title, artist 등의 정보가 필요하다.
따라서 필요한 데이터의 형태를 Data Class
로 정의한다.
New > Kotlin Class/File > Data Class 생성
data class Chart (
val cover: Int,
val title: String,
val artist: String
)
이제 아이템과 틀은 준비되었고, 둘을 연결시켜야 한다.
RecyclerView에서는 ViewHolder
패턴을 사용해 데이터가 효율적으로 틀 안에 들어갈 수 있도록 기능을 정의한다.
실제 ViewHolder 코드는 다음 단계인 4번, Adapter 클래스 안에 작성할 것이기 때문에 지금은 예시 코드만 보도록 하자.
class ViewHolder(private val binding: ItemHomeChartBinding) : RecyclerView.ViewHolder(binding.root){
fun onBind(chart: Chart){
binding.ivChartCover.setImageResource(chart.cover)
binding.tvChartTitle.text = chart.title
binding.tvChartArtist.text = chart.artist
}
}
binding
은 findViewById 대신에 효율적으로 데이터와 레이아웃을 연결한다.binding
을 사용하려면 앱의 .gradle
파일에 바인딩 사용을 명시해야 한다.❗️android {
...
buildFeatures {
viewBinding true
}
}
ItemHomeChartBinding
은 item_home_chart.xml
을 바인딩한 것binding.tvChartTitle
은 item_home_chart.xml의 tv_chart_title
을 바인딩한 것이제 ViewHolder에서 정의한 기능을 실제로 레이아웃에 구현하는 Adapter
를 만들어야 한다.
Adapter
는 미리 생성해둔 뷰홀더 객체에 사용자가 원하는 data list를 넣고, 변경사항을 UI에 반영하는 역할을 한다.
ViewHolder
가 아이템 하나에 data class로 정의한 값을 넣는다면,
Adapter
는 UI에 아이템들을 연결해 보여주는 역할을 한다고 생각하면 편하겠다.
Adapter를 구현하려면 다음과 같은 단계가 필요하다.
onCreateViewHolder()
onBindViewHolder()
getItemCount()
구현한 코드는 다음과 같다.
ChartAdapter
class ChartAdapter : RecyclerView.Adapter<ChartAdapter.ViewHolder> () {
// list로 보여줄 아이템 미리 정의 -> 나중에 activity/fragment에서 구현할 때 실제 데이터 추가
var chartList = mutableListOf<Chart>()
class ViewHolder(private val binding: ItemHomeChartBinding) : RecyclerView.ViewHolder(binding.root){
fun onBind(chart: Chart){
binding.ivChartCover.setImageResource(chart.cover)
binding.tvChartTitle.text = chart.title
binding.tvChartArtist.text = chart.artist
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemHomeChartBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.onBind(chartList[position])
}
override fun getItemCount(): Int {
return chartList.size
}
}
부착하기 위해서는 다음과 같은 단계가 필요하다.
구현한 코드는 다음과 같다.
HomeActivity
class HomeActivity: AppCompatActivity() {
// 바인딩
lateinit var binding: ActivityHomeBinding
// 어댑터 객체 선언
private lateinit var chartAdapter: ChartAdapter
// 아이템 데이터 리스트 선언
private val chartData = mutableListOf<Chart>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
initializeList()
initChartRecyclerView()
}
private fun initChartRecyclerView() {
// 1. 어댑터 생성
chartAdapter = ChartAdapter()
// 2. 데이터를 어댑터 안에 넣기
chartAdapter.chartList = chartData
// 3. RecyclerView의 어댑터를 만든 어댑터로 설정
binding.rvChart.adapter = chartAdapter
}
private fun initializeList() {
with(chartData) {
add(Chart(R.drawable.cover,"Hype Boy","NewJeans"))
add(Chart(R.drawable.cover,"ANTIFRAGILE","LE SSERAFIM (르세라핌)"))
add(Chart(R.drawable.cover,"Nxde","(여자)아이들"))
add(Chart(R.drawable.cover,"Hype Boy","NewJeans"))
add(Chart(R.drawable.cover,"ANTIFRAGILE","LE SSERAFIM (르세라핌)"))
add(Chart(R.drawable.cover,"Nxde","(여자)아이들"))
add(Chart(R.drawable.cover,"Hype Boy","NewJeans"))
add(Chart(R.drawable.cover,"ANTIFRAGILE","LE SSERAFIM (르세라핌)"))
add(Chart(R.drawable.cover,"Nxde","(여자)아이들"))
}
}
}
참고
https://velog.io/@l2hyunwoo/Android-기능-구현-5
https://velog.io/@24hyunji/AndroidKotlin-RecyclerView-사용해보기