728x90
RecyclerView란?
RecyclerView는 안드로이드 앱에서 리스트 형태의 데이터를 표시하는데 사용되는 위젯이다. 여러 아이템을 스크롤 가능한 리스트로 표현하며, 많은 아이템을 효율적으로 관리하고 보여주는 역할을 한다.
- RecyclerView는 한정적인 화면에 많은 데이터를 넣을 수 있는 View
- View를 재활용해서 사용한다.
ListView 와 RecyclerView 차이
ListView
- 사용자가 스크롤 할 때마다 위에 있던 아이템은 삭제되고, 맨 아래의 아이템은 생성 되길 반복한다.
- 아이템이 100개면 100이 삭제 생성된다. 즉 계속 삭제와 생성을 반복하므로 성능에 좋지않다.
RecyclerView
- 사용자가 스크롤 할 때, 위에 있던 아이템은 재활용 돼서 아래로 이동하여 재사용 한다.
- 즉 아이템이 100개여도 10개정도의 View만 만들고 10개를 재활용해서 사용한다.
- View를 계속 만드는 ListView의 단점을 보완하기 위해 나왔다.
RecyclerView사용하기
Adapter
- Adapter란 데이터 테이블을 목록 형태로 보여주기 위해 사용되는 것으로, 데이터를 다양한 형식의 리스트 형식을 보여주기 위해서 데이터와 RecyclerView 사이에 존재하는 객체이다.
- 즉 데이터와 RecyclerView 사이의 통신을 위한 연결체이다.
ViewHolder
- ViewHolder란 화면에 표시될 데이터나 아이템들을 저장하는 역할이다.
- RecyclerView의 개념을 적용하기위해선 스크롤 해서 위로 올라간 View를 재활용하기 위해서 이 View를 기억하고 있어야 한다. ViewHolder가 그역할을 한다.
예제
activity_main.xml
더보기
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_profile.xml
더보기
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_profile"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_margin="36dp"
android:src="@drawable/image_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="이름 : "
android:textSize="18sp"
app:layout_constraintStart_toEndOf="@id/iv_profile"
app:layout_constraintTop_toTopOf="@id/iv_profile" />
<TextView
android:id="@+id/tv_Age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="나이 : "
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@id/tv_Name"
app:layout_constraintTop_toBottomOf="@id/tv_Name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_NameText"
app:layout_constraintTop_toTopOf="@id/tv_Name"
app:layout_constraintBottom_toBottomOf="@id/tv_Name"
android:text="김아무개"
app:layout_constraintStart_toEndOf="@id/tv_Name"
android:layout_marginStart="7dp"
android:textSize="18sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_AgeText"
app:layout_constraintTop_toTopOf="@id/tv_Age"
app:layout_constraintBottom_toBottomOf="@id/tv_Age"
android:text="17"
app:layout_constraintStart_toEndOf="@id/tv_Name"
android:layout_marginStart="7dp"
android:textSize="18sp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
ItemAdapter
class ItemAdapter(private val list: List<Profile>) :
RecyclerView.Adapter<ItemAdapter.ProfileViewHolder>() {
inner class ProfileViewHolder(private val binding: ItemProfileBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(profile: Profile) {
binding.tvNameText.text = profile.name
binding.tvAgeText.text = profile.age.toString()
}
}
//뷰홀더 생성
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileViewHolder {
val inflater =
parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val binding = ItemProfileBinding.inflate(inflater, parent, false)
return ProfileViewHolder(binding)
}
//재사용 할 아이템 수
override fun getItemCount() = list.size
//데이터 연결
override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) {
val profile = list[position]
holder.bind(profile)
//bind -> ProfileViewHolder의 bind(데이터 연결)
}
}
데이터 클래스
data class Profile(val name: String, val age: Int)
MainAcativity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var itemAdapter: ItemAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//더미 데이터
itemAdapter = ItemAdapter(listOf(Profile("김",16),Profile("나",22),Profile("박",65),Profile("이",23)))
//recyclerView 세팅
binding.recyclerView.apply {
//adapter 연결
adapter = itemAdapter
//layout 설정 GridLayout 가능
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
}
}
}