오늘은 listview와 비슷한 RecylcerView를 알아보는 시간을 갖도록 하겠습니다.
Recyle → 재활용하다.
View를 재활용하여 사용하는 방법
ListView와 RecyclerView의 차이점
- ListView
스크롤 할 때마다 위에 있던 아이템은 삭제되고,
맨 아래 아이템은 생성 되길 반복합니다.
아이템 개수 만큼 삭제와 생성을 반복하여 성능에 좋지 않습니다.
- RecyclerView
스크롤 할 때마다 위에 있던 아이템이 재활용 되어 아래로 이동하여 재사용 됩니다.
예를 들어 10개 정도 View를 만들고 10개를 재활용하여 사용합니다.
View를 계속 만드는 ListView의 단점을 보완할 수 있습니다.
데이터를 목록 형태로 보여주기 위해 사용됩니다.
데이터를 아이템 뷰와 연결하는 역할을 합니다.
데이터와 RecyclerView 사이의 통신을 위한 연결체 입니다.
아이템 뷰를 보유(저장)하고 표시하는 역할을 합니다.
스크롤 해서 위로 올라간 View를 재활용하기 위해 View를 기억하는 역할을 합니다.
데이터나 아이템들이 리사이클러뷰 내부에서 배치되는 형태(방식)을 관리합니다.
종류
LinearLayoutManager : 수평, 수직으로 배치 시켜줍니다.
GridLayoutManager : 그리드 화면으로 배치 시켜줍니다.
StaggeredGridLayoutManager : 높이가 불규칙한 그리드 화면으로 배치 시켜줍니다.
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/rv_item"
android:text="rv"
android:textSize="20sp"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints"/>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.sangmoki.rv_practice
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
// RecyclerView에 들어갈 아이템 리스트 생성
val items = mutableListOf<String>()
// 아이템 리스트에 아이템 추가
items.add("1")
items.add("2")
items.add("3")
// RecyclerView에 Adapter 연결
val rv = findViewById<RecyclerView>(R.id.rv)
val rvAdapter = RvAdapter(items)
// RecyclerView에 Adapter 설정
rv.adapter = rvAdapter
// RecyclerView의 레이아웃 매니저 설정
rv.layoutManager = LinearLayoutManager(this)
}
}
package com.sangmoki.rv_practice
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RvAdapter(val items: MutableList<String>) : RecyclerView.Adapter<RvAdapter.ViewHolder>() {
var itemClick : ItemClick ? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvAdapter.ViewHolder {
// 뷰홀더를 생성하고 뷰를 붙여주는 부분
var view = LayoutInflater.from(parent.context).inflate(R.layout.rv_item, parent, false)
// 생성한 뷰를 ViewHolder에 넣어 반환
return ViewHolder(view)
}
override fun onBindViewHolder(holder: RvAdapter.ViewHolder, position: Int) {
// items 리스트에서 position에 해당하는 데이터를 가져온다.
val item = items[position]
// itemClick이 되었을 때 실행 조건
if (itemClick != null) {
// 클릭 이벤트 구현
holder.itemView.setOnClickListener { v ->
itemClick?.onClick(v, position)
}
}
// bindItem 메소드를 호출하여 데이터를 뷰에 바인딩한다.
holder.bindItem(item)
}
override fun getItemCount(): Int {
// items 리스트의 크기를 반환한다.
return items.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
// 뷰홀더에 각각의 아이템을 바인딩하는 역할을 하는 메소드
fun bindItem(item: String) {
// rv_item layout의 id를 가져와 text를 item으로 치환해준다.
val rv_text = itemView.findViewById<TextView>(R.id.rv_item)
rv_text.text = item
}
}
// 클릭 이벤트를 위한 인터페이스 정의
interface ItemClick {
fun onClick(view: View, position: Int)
}
}
var itemClick : ItemClick ? = null
// 클릭 이벤트를 위한 인터페이스 정의
interface ItemClick {
fun onClick(view: View, position: Int)
}
override fun onBindViewHolder(holder: RvAdapter.ViewHolder, position: Int) {
// items 리스트에서 position에 해당하는 데이터를 가져온다.
val item = items[position]
// itemClick이 되었을 때 실행 조건
if (itemClick != null) {
// 클릭 이벤트 구현
holder.itemView.setOnClickListener { v ->
itemClick?.onClick(v, position)
}
}
// bindItem 메소드를 호출하여 데이터를 뷰에 바인딩한다.
holder.bindItem(item)
}
오늘은 RecyclerView에 대해 알아보았는데, ListView와의 비교를 정리해보자면, RecylcerView는 직접 클릭이벤트를 작성해주어야 하는 번거로움이 있지만, ViewHolder를 통하여 재사용할 수 있는 장점이 있어 ListView보다 성능이 좋다는 장점을 가지고 있습니다.