Kotlin/예제 정리

예제 정리 : 리사이클러 뷰(RecyclerView)

바보인간 2023. 2. 19. 15:53

1. 리사이클러 뷰

1-1. 정의

리사이클러뷰는 안드로이드에서 많이 사용되는 뷰 중 하나이다.

대량의 데이터를 리스트나 그리드 형태로 표시할 때 사용된다.

리사이클러뷰는 리스트뷰나 그리드뷰와 유사하지만, 성능면에서 우수하고 더 많은 커스터마이징이 가능하다.

뷰 객체를 처음에 생성하고 그것을 돌려 쓰기 때문에 Cost 관점에서 효과적이다.

다만, 뷰 홀더라는 클래스가 필요하다.

리스트 뷰와 리사이클러 뷰

1-2. 사용 방법

1) RecyclerView 를 레이아웃 파일에 추가한다.

2) 아이템뷰의 레이아웃 파일을 작성한다.

3) 어댑터를 작성하여 아이템뷰를 관리한다.

4) 리사이클러뷰에 레이아웃 매니저와 어댑터를 설정한다.

 

사실상 기본적인 사용법은 거의 정해져 있어서. 인터넷에 소스를 참고하면 쉽게 구현할 수 있다.

 

2. 예시 코드

2-1. 결과

리사이클러 뷰 실행 예시

2-2. 리사이클러뷰 레이아웃에 추가

<?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=".ui.MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_board"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/itme_recycler"/>

</androidx.constraintlayout.widget.ConstraintLayout>

여기서 tools:listitem ="@layout/itme_recycler" 는 레이아웃에 아이템 모양을 적용해 보여준다.

 

2-3. 아이템 레이아웃 제작

<?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="wrap_content"
    android:orientation="horizontal"
    android:paddingHorizontal="15dp"
    android:paddingVertical="20dp">

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="15:43"/>

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingHorizontal="10dp"
        android:text="글 제목"/>

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="바보인간"/>

</LinearLayout>

 

2-4. 어댑터 작성 및 데이터 클래스 제작

[BoardItem.kt]

package com.example.recyclerview.data

data class BoardItem(
    val time: String,
    val title: String,
    val name: String
)

[BoardAdapter.kt]

package com.example.recyclerview.ui

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.example.recyclerview.data.BoardItem
import com.example.recyclerview.databinding.ItmeRecyclerBinding


class BoardAdapter(private val itemList: ArrayList<BoardItem>): RecyclerView.Adapter<BoardAdapter.BoardViewHolder>() {
    inner class BoardViewHolder(private val binding: ItmeRecyclerBinding): ViewHolder(binding.root) {
        fun bind(item:BoardItem){
            binding.tvTime.text = item.time
            binding.tvTitle.text = item.title
            binding.tvName.text = item.name
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BoardViewHolder {
        val binding = ItmeRecyclerBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return BoardViewHolder(binding)
    }

    override fun getItemCount(): Int {
        return itemList.size
    }

    override fun onBindViewHolder(holder: BoardViewHolder, position: Int) {
        val item = itemList[position]
        holder.bind(item)
    }


}

데이터 클래스를 만들고, 어댑터에 있는 기본적인 함수를 오버라이딩 해서 제작하였다.

전체적인 형식은 대부분 비슷하고, BoardViewHolder는 뷰 바인딩을 이용해서 제작하였다.

뷰 바인딩을 이용하는 것이 findViewById를 사용하는 것보다 안정적이라고 한다.

 

2-4. 리사이클러뷰에 레이아웃 매니저와 어댑터 설정

package com.example.recyclerview.ui

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.recyclerview.R
import com.example.recyclerview.data.BoardItem
import com.example.recyclerview.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var mainBinding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mainBinding.root)

        val itemList = ArrayList<BoardItem>()
        for (i in 1..20) {
            itemList.add(BoardItem("$i:00", "제목 $i", "작성자 $i"))
        }

        val boardAdapter = BoardAdapter(itemList)
        boardAdapter.notifyDataSetChanged()

        mainBinding.rvBoard.adapter = boardAdapter
        mainBinding.rvBoard.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)


    }
}

반복문으로 아이템을 추가해주고, 어댑터를 연결해준다.

notifyDataSetChanged는 어댑터가 가지고 있는 데이터셋이 변경되면 이를 리사이클러뷰에 알려주는 메서드이다.

즉, 리사이클러 뷰가 아이템뷰를 재활용하여서, 실제 우리가 필요한 분량만 보여줄 때 필요한 메서드이다.