RecyclerView란?
동일한 형식으로 여러 번 반복되는 뷰 그룹을 레이아웃 상에서 일일이 생성하는 것은 매우 비효율적일 것입니다.
동일한 형식으로 반복되는 뷰와 데이터를 처리할 때 RecyclerView 라이브러리를 사용해 요소를 동적으로 생성합니다.
RecyclerView는 데이터 집합들을 각각의 개별 아이템 단위로 구성하여 화면에 출력하는 뷰 그룹이며, 많은 데이터를 스크롤 가능한 리스트 형태로 구현할 때 사용합니다.
쉽게 말해, 동일한 형식의 데이터 그룹을 하나의 아이템으로 구성해 아이템 리스트를 출력한다고 볼 수 있습니다.
카카오톡 채팅방이나 SNS 게시물, 배달의 민족 매장 목록 등 많은 앱에서 볼 수 있는 형태입니다.
RecyclerView의 주요 클래스
- 데이터 집합을 각각의 개별 아이템 단위의 뷰가 포함된 ViewGroup
- 각각의 뷰를 보관하는 ViewHolder, ViewHolder생성 후 한 번만 바인딩하며, 바인딩된 객체에 접근하기 때문에 효율적입니다.
- 뷰를 뷰의 데이터에 바인딩하는 Adapter
- 뷰의 배치를 담당하는 Layout Manager
RecyclerView의 구현 단계
- RcyclerView를 레이아웃에 추가하고 각 아이템의 레이아웃을 설정합니다.
- 아이템에 들어갈 데이터 클래스를 생성합니다.
- 아이템을 관리할 ViewHolder와 목록을 관리할 Adapter를 정의합니다.
- RecyclerView와 Adapter를 연결합니다.
이제 RecyclerView 사용예제를 작성해 보겠습니다.
RecyclerView 사용예제
먼저 build.gradle(Module: app)에 뷰 바인딩과 의존성을 추가합니다.
android {
...
buildFeatures {
viewBinding true
}
dependencies {
...
implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
item_recyclerview.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="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:background="#BCD8E3">
<ImageView
android:id="@+id/iv_profile"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@color/black"/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:text="이름"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/iv_profile"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_phone_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="전화번호"
android:textColor="#000000"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="@+id/tv_name"
app:layout_constraintTop_toBottomOf="@+id/tv_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
레이아웃에 RecyclerView컴포넌트를 추가하고, RecyclerView의 아이템이 될 레이아웃을 생성했습니다.
Person (Data Class)
data class Person(
val img : Int, // Drawable 파일
val name : String, // 오제이
val phoneNumber : String // 010-xxxx-xxxx
)
RecyclerView 목록에서 보여줄 데이터 클래스를 생성합니다.
RecyclerViewAdapter
class RecyclerViewAdapter(private val list : ArrayList<Person>): RecyclerView.Adapter<RecyclerViewAdapter.CustomViewHolder>() {
inner class CustomViewHolder(private val binding: ItemRecyclerviewBinding): RecyclerView.ViewHolder(binding.root) {
fun bind(item: Person) {
binding.ivProfile.setImageResource(item.img)
binding.tvName.text = item.name
binding.tvPhoneNumber.text = item.phoneNumber
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val view = ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return CustomViewHolder(view)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
holder.bind(list[position])
}
override fun getItemCount()= list.size
}
RecyclerView의 목록을 관리할 Adapter입니다.
RecyclerView 각각의 아이템이 될 ViewHolder를 inner class로 정의합니다. ViewHolder는 목록에서 개별 항목의 레이아웃을 바인딩하고, Adapter에서 필요시 ViewHolder 객체에 접근하여 뷰와 데이터를 설정합니다.
Adapter를 구현할 때에는 RecyclerView.Adapter를 상속받기 때문에 반드시 세 개의 메소드를 재정의(override)해야 합니다.
- onCreateViewHolder : ViewHolder와 그에 연결된 뷰를 생성
- onBindViewHolder : 아이템의 뷰에 데이터를 연결 (ViewHolder와 데이터 연결)
- getItemCount : RecyclerView 아이템(항목)의 개수
MainActivity
class MainActivity : AppCompatActivity() {
private val binding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
private lateinit var recyclerViewAdapter: RecyclerViewAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val list = ArrayList<Person>()
list.add(Person(R.drawable.ic_profile,"오제이","010-1234-1234"))
list.add(Person(R.drawable.ic_profile,"홍길동","010-1111-2222"))
list.add(Person(R.drawable.ic_profile,"마이네임","010-0000-0000"))
recyclerViewAdapter = RecyclerViewAdapter(list)
binding.mainRecyclerview.apply {
layoutManager = LinearLayoutManager(applicationContext)
adapter = recyclerViewAdapter
}
}
}
마지막으로 MainActivity에서 RecyclerView와 Adapter를 연결하고 layoutManager를 설정합니다. layoutManager는 가로/세로, 그리드 형식을 지정할 수 있습니다.
실행결과
'Android' 카테고리의 다른 글
[안드로이드] Fragment 터치 시 뒤의 화면까지 터치되는 현상 (0) | 2023.01.19 |
---|---|
[안드로이드] Bottom NavigationView 텍스트, 아이콘 색상 변경 (1) | 2023.01.18 |
[Android] 탭 레이아웃(TabLayout) 적용하기 (2) | 2023.01.14 |
[Android] 안드로이드 Retrofit(레트로핏) 사용법 - 경기도데이터드림 OPEN API 사용해보기 (2) | 2023.01.13 |
[Android] ListAdapter 사용 중 리스트가 갱신되지 않은 문제 (1) | 2023.01.13 |