RecyclerView는 이미지나 텍스트를 리스트화하고, 스크롤하며 볼 수 있게 해주는 컨테이너입니다.
이번에 RecyclerView를 사용하여, 리스트에 있는 문자열을 보여주는 앱을 만들어보겠습니다.
먼저 메인 화면에 RecyclerView를 추가한 후, id를 recyclerView로 해주겠습니다.
<?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="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
다음으로 문자열 리스트를 받는 RecyclerView의 Adapter를 만들어주어야합니다.
RVAdapter.kt를 만들어 주고 인자로 문자열 리스트를 받게하겠습니다.
RVAdapter는 RVAdapter의 viewHolder를 타입으로 갖는 Adapter를 반환해야합니다.
하지만 viewHolder는 직접 inner 클래스로 만들어주어야합니다.
viewHolder에 문자열 리스트의 원소를 하나하나 다른 view로 만들어주는 메서드를 만들어야합니다.
이를 bindItems라는 이름으로 만들겠습니다.
package com.example.recyclerview_ex
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class RVAdapter(val items : MutableList<String>) : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
...
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
}
}
}
RecyclerView에 들어갈 문자열들이 보일 화면을 만들어주겠습니다.
recyclerview_item.xml을 만들어 다음과 같이 만들었습니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp">
<TextView
android:id="@+id/recyclerViewItem"
android:text="item"
android:textSize="20sp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
위와같이 보일 예정입니다.
이제 bindItems 메서드 안에 문자열을 받아 화면으로 만들어주는 코드를 추가해주겠습니다.
package com.example.recyclerview_ex
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RVAdapter(val items : MutableList<String>) : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
...
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
이쯤에서 RVAdapter를 보면 빨갛게 밑줄이 그어진 것이 보입니다.
이는 추가해야할 메서드들을 아직 추가하지 않았기 때문입니다.
필요한 메서드들을 추가하겠습니다.
package com.example.recyclerview_ex
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>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
}
override fun getItemCount(): Int {
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
onCreateViewHolder는 말그대로 viewHolder라는 틀을 만들어서 반환하는 메서드입니다.
viewHolder는 이전에 만들어놓은 recyclerview_item.xml를 LayoutInflater를 통해 view로 만들어준 후, viewHolder를 생성해 반환해야합니다.
package com.example.recyclerview_ex
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>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.recyclerview_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
}
override fun getItemCount(): Int {
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
다음은 onBindViewHolder입니다.
viewHolder에서 만들어줄 화면에 postition에 위치한 문자열을 넣어주어야합니다.
인자로 받은 holder의 bindItems에 넣어주겠습니다.
package com.example.recyclerview_ex
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>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.recyclerview_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(items[position])
}
override fun getItemCount(): Int {
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
마지막으로 getItemCount 메서드입니다.
이름에서 유추할 수 있듯, 리스트의 길이를 반환해주면 됩니다.
package com.example.recyclerview_ex
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>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.recyclerview_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(items[position])
}
override fun getItemCount(): Int {
return items.size
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
이렇게 Adapter가 완성되었습니다.
이제 MainActivity.kt에서 작업을 마무리하겠습니다.
문자열을 타입으로 갖는 리스트를 생성해준 후, 몇개의 요소들을 넣어줍니다.
RecyclerView를 findViewById를 통해 찾아 변수 넣어주고, 위에서 만든 Adpater도 생성하여 변수에 넣어주겠습니다.
또한 생성한 Adapter를 RecyclerView의 Adapter에 넣어줍니다.
이후, LinearLayoutManager를 만들어 RecyclerView의 layoutManager에 넣어주겠습니다.
package com.example.recyclerview_ex
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val items = mutableListOf<String>()
items.add("a")
items.add("b")
items.add("c")
items.add("d")
items.add("e")
val recyclerview = findViewById<RecyclerView>(R.id.recyclerView)
val recyclerviewAdapter = RVAdapter(items)
recyclerview.adapter = recyclerviewAdapter
recyclerview.layoutManager = LinearLayoutManager(this)
}
}
RecyclerView를 사용해보았습니다.
이제 클릭 이벤트를 처리해보겠습니다.
ListView와 다르게 RecyclerView는 들어갈 item에 setOnItemClickListener를 설정해줄 수 없습니다.
예상하셨나요? 직접 만들어주어야합니다.
다시 RVAdapter.kt로 돌아가겠습니다.
먼저 ItemClick이라는 인터페이스를 만들어주고, onClick이라는 메서드를 정의해줍니다.
그리고 itemClick이라는 변수를 만든 후, null을 할당해주겠습니다.
package com.example.recyclerview_ex
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>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.recyclerview_item, parent, false)
return ViewHolder(view)
}
// 클릭 이벤트를 위한 인터페이스
interface ItemClick {
fun onClick(view : View, position: Int) {}
}
var itemClick : ItemClick? = null
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(items[position])
}
override fun getItemCount(): Int {
return items.size
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
RecyclerView에 들어갈 recyclerview_item 화면을 만들어주는건 onBindViewHolder이기 때문에 여기에 만들어줄 화면에 대한 setOnClickListener를 설정해주어야합니다.
어떤 동작을 할 것인지는 사용하는 위치에서 정의하도록 만들겠습니다.
package com.example.recyclerview_ex
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>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.recyclerview_item, parent, false)
return ViewHolder(view)
}
// 클릭 이벤트를 위한 인터페이스
interface ItemClick {
fun onClick(view : View, position: Int) {}
}
var itemClick : ItemClick? = null
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// 사용하는 위치에서 동작을 정의하도록 한다.
if (itemClick != null) {
holder.itemView.setOnClickListener{
v -> itemClick?.onClick(v, position)
}
}
holder.bindItems(items[position])
}
override fun getItemCount(): Int {
return items.size
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(item : String) {
val recyclerviewItem = itemView.findViewById<TextView>(R.id.recyclerViewItem)
recyclerviewItem.text = item
}
}
}
이제 다시 MainActivity.kt로 돌아가겠습니다.
이제 클릭하면 어떤 동작을 할지 작성해야합니다.
이번 앱에서는 각 item의 문자열을 Toast메시지로 띄울 예정입니다.
이를 Adapter의 itemClick을 새로 정의해 넣어주겠습니다.
package com.example.recyclerview_ex
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val items = mutableListOf<String>()
items.add("a")
items.add("b")
items.add("c")
items.add("d")
items.add("e")
val recyclerview = findViewById<RecyclerView>(R.id.recyclerView)
val recyclerviewAdapter = RVAdapter(items)
recyclerview.adapter = recyclerviewAdapter
recyclerview.layoutManager = LinearLayoutManager(this)
recyclerviewAdapter.itemClick = object : RVAdapter.ItemClick {
override fun onClick(view: View, position: Int) {
Toast.makeText(baseContext, items[position], Toast.LENGTH_SHORT).show()
}
}
}
}
'안드로이드' 카테고리의 다른 글
[안드로이드] getBitmap 메서드와 성능 (1) | 2023.01.19 |
---|---|
[안드로이드] ViewBinding 사용해보기 (0) | 2022.05.24 |
[안드로이드] 뒤로 가기 두 번 누르면 종료되게 만들기 (0) | 2022.05.11 |
[안드로이드] ListView 구현하기 (0) | 2022.05.11 |
[안드로이드] DataBinding 으로 TextView 업데이트 하기 (0) | 2022.05.10 |