본문 바로가기
Android

[Kotlin] RecyclerView 사용하기

by bryan.oh 2023. 8. 17.
반응형

RecyclerView

 

아래 두가지 방법에 대해서 예제를 들어보겠습니다.

1. findViewById

2. viewBinding

 

우선 Activity 를 생성합니다.

class RecyclerViewTestActivity : AppCompatActivity() {
    private lateinit var binding: ActivityRecyclerViewTestBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityRecyclerViewTestBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }
}

layout 파일에 RecyclerView 를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".RecyclerViewTestActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

 

Adapter 추가

파일을 만들 위치에서(저는 adapters 라는 package 를 만들었습니다.) 우클릭 해서 new > Kotlin class/file 선택

파일이름은 PersonAdapter

class PersonAdapter : RecyclerView.Adapter<PersonAdapter.ViewHolder>() {
}

그리고 RecyclerView 에서 사용할 data class 를 생성합니다.

 

Item Class 추가

파일 경로에서 우클릭 > new > Kotlin class/file 선택 > Person 입력

Person.kt

data class Person (
    var name: String,
    var mobile: String
)

 

RecyclerView의 Item 에 사용될 Layout 추가

layout 우클릭 > New > Layout Resource File

File Name : person
Root Element : LineanerLayout

더보기
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="@dimen/person_text_size"
            android:text="이름 : " />

        <TextView
            android:id="@+id/person_name_textview"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:textSize="@dimen/person_text_size"
            android:text="" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="@dimen/person_text_size"
            android:text="전화번호 : " />

        <TextView
            android:id="@+id/person_mobile_textview"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:textSize="@dimen/person_text_size"
            android:text="" />
    </LinearLayout>
</LinearLayout>

 

findViewById 스타일의 Adapter

class PersonAdapter : RecyclerView.Adapter<PersonAdapter.ViewHolder>() {

    var items = ArrayList<Person>()
    
    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun setItem(item: Person){
            var nameTv = itemView.findViewById<TextView>(R.id.person_name_textview)
            nameTv.setText(item.name)

            var mobileTv = itemView.findViewById<TextView>(R.id.person_mobile_textview)
            mobileTv.setText(item.mobile)
        }
    }
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.person, parent, false)
        return ViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = items[position]
        holder.setItem(item)
    }

    override fun getItemCount(): Int {
        return items.count()
    }
}

 

이제 Activity 에서 RecyclerView 를 추가합니다.

Activity 의 onCreate() 안에서,

class RecyclerViewTestActivity : AppCompatActivity() {
    private lateinit var binding: ActivityRecyclerViewTestBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityRecyclerViewTestBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        binding.recyclerRecyclerview.layoutManager = layoutManager

        val adapter = PersonAdapter()

        adapter.items.add(Person("홍길동", "010-1234-1234"))
        adapter.items.add(Person("김철수", "010-1111-1111"))
        adapter.items.add(Person("임꺽정", "010-2222-2222"))

        binding.recyclerRecyclerview.adapter = adapter
    }
}

adapter 의 items 에 직접 add 를 해도 되고,

아래와 같이 ArrayList<Person>() 을 직접 넘기도록 Activity 코드를 수정해도됩니다.

        val personList = ArrayList<Person>()
        personList.add(Person("홍길동", "010-1234-1234"))
        personList.add(Person("김철수", "010-1111-1111"))
        personList.add(Person("임꺽정", "010-2222-2222"))

        val adapter = PersonAdapter(personList)

그럼 Adapter의 생성자를 변경해야겠죠.

class PersonAdapter(private var items: ArrayList<Person>) : RecyclerView.Adapter<PersonAdapter.ViewHolder>() {
// class 파라메터 추가

//    아래는 삭제
//    var items = ArrayList<Person>()

 

 

ViewBinding 스타일의 Adapter

class PersonAdapter(private var items: ArrayList<Person>) : RecyclerView.Adapter<PersonAdapter.ViewHolder>() {

    inner class ViewHolder(private val binding: PersonBinding) : RecyclerView.ViewHolder(binding.root) {

        fun setItem(item: Person){
            binding.personNameTextview.text = item.name
            binding.personMobileTextview.text = item.mobile
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.person, parent, false)
        return ViewHolder(PersonBinding.bind(itemView))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = items[position]
        holder.setItem(item)
    }

    override fun getItemCount(): Int {
        return items.count()
    }
}

변경된 부분

  • inner class ViewHolder(private val binding: PersonBinding) : RecyclerView.ViewHolder(binding.root) {
  • fun setItem 에서 binding 을 사용해서 TextView 에 접근
  • onCreateViewHolder() 에서 return ViewHolder(PersonBinding.bind(itemView)) 으로 변경

 

다음 글에서는 여기에 ClickListener 를 추가해보겠습니다.

728x90
반응형

댓글