Android androidx: 리사이클러 뷰 1

timothy jeong·2021년 11월 8일
0

Android with Kotlin

목록 보기
25/69

왜 리사이클러 뷰를 사용하는가?

리사이클러 뷰는 데이터 리스트를 화면에 표시하는데 있어서 유용한 뷰이다. 리사이클러 뷰를 이용하는 이점은 다음과 같다.

(1) list를 구성하는 각각의 item 이 레이아웃을 갖기 때문에 UI 를 풍부하게 구성할 수 있다.
(2) list item 을 위치시키는데 다양한 방법을 지원한다.
(3) 네비게이션과 호환이 된다.
(4) 큰 규모의 리스트를 다루는데 효율적이다. -> 스크롤 off 되어 사라진 item 을 새롭게 scroll on 되어진 item 을 만드는데 사용하기 때문이다.

리사이클러 뷰 기초 사용법

RecyclerView 클래스만으로 화면에 아무것도 출력되지 않는다. 그러므로 다음의 구성요를 추가해야한다.

  • ViewHolder(필수): 항목에 필요한 뷰 객체를 가진다.
  • Adapter(필수): 각 항목에 들어간 뷰 객체가 필요한 데이터를 대입해 항목을 완성한다.
  • LayoutManager(필수): 항목을 배치한다.
  • ItemDecoration(옵션): 항목을 꾸민다.

리스트뷰와 리사이클러 뷰
원래는 API 1 레벨부터 제공되던 리스트뷰가 목록을 구성할때 사용되었지만, androidx 라이브러리가 리사이클뷰를 제공하기 시작하면서부터 많은 개발자가 목록 화면을 리사이클러 뷰로 만들고 있다.

리사이클러 뷰를 사용하고자 할때 아래와 같이 개별 의존성을 추가해도 되지만,

implementation 'androidx.recyclerview:recyclerview:1.2.0'

안드로이드 스튜디오 4.1 이상부터는 머티리얼 디자인 라이브러리가 자동으로 추가되어있고, 이 라이브러리가 androidx 의 많은 라이브러리를 이용하기 때문에 굳이 하지 않아도 되는 것이 많다.

리아시클러 뷰, 내부 항목 레이아웃

리사이클러 뷰를 만들고,

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

</androidx.recyclerview.widget.RecyclerView>

리사이클러 뷰 내부에 표시할 항목을 디자인한 레이아웃을 만들자

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/item_root"
    android:orientation="horizontal"
    android:padding="16dp">
    <TextView
        android:id="@+id/item_data"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="20dp"
        android:textStyle="bold"
        android:textSize="16sp"/>
</LinearLayout>

뷰 홀더와 어댑터 코드

그리고 뷰 홀더와 어댑터를 만든다.

class MyViewHolder(val binding: ItemMainBinding): RecyclerView.ViewHolder(binding.root) {
    
}
class MyAdapter(private val datas: List<String>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    override fun getItemCount(): Int = datas.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = MyViewHolder(ItemMainBinding.inflate(LayoutInflater.from(parent.context), parent, false))

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        Log.d("Info", "onBindViewHolder : $position")
        val binding = (holder as MyViewHolder).binding
        // 뷰에 데이터 출력
        binding.itemData.text = datas[position]
        // 뷰에 이벤트 추가
        binding.itemRoot.setOnClickListener{
            Log.d("Info", "item root click : $position")
        }
    }
}

어댑터에서 override 해야하는 함수는

  • getItemCount(): 항목 개수를 판단하려고 자동으로 호출된다. 이 함수가 반환한 숫자만큼 onBindViewHolder() 함수가 호출되어 항목을 만든다. 만약 이 함수가 0을 반환하면 화면에 아무것도 나오지 않는다.

  • onCreateViewHolder(): 항목의 뷰를 가지는 뷰 홀더를 준비하려고 자동으로 호출된다. 여기서 반환하는 뷰 홀더 객체는 자동으로 onBindViewHolder() 의 매개변수로 전달된다.

  • onBindViewHolder(): 뷰 홀더의 뷰에 데이터를 출력하려고 자동으로 호출된다. 매개변수로 전달된 뷰 홀더 객체의 뷰에 데이터를 출력하거나 필요한 이벤트를 등록한다. 두번째 매개변수가 항목의 인덱스이다.

액티비티 코드

그리고 마지막으로 액티비티에서 리사이클러 뷰를 이용하도록 코드를 설정하면 된다.

class MainActivity : AppCompatActivity() {

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

        val datas = mutableListOf<String>()
        for(i in 1..10) {
            datas.add("Item $i")
        }
        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = MyAdapter(datas)
        binding.recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
    }
}

항목을 동적으로 추가, 제거

리사이클러 뷰에 항목이 출력된 후 동적으로 새로운 항목을 추가하거나 화면에 보이는 항목을 제거해야할 때가 있다. 이 작업은 항목을 구성하는 데이터에 새로운 데이터를 추가하거나 제거한 후 어댑터의 notifyDataSetChanged() 함수를 호출하면 된다.

예를들어, 다음과 같이 하는 식인데, 뷰 바인딩을 쓸때 이를 어떻게 동적으로 처리하는지는 모르겠다.

datas.clear
adapter.notifyDataSetChanged()
profile
개발자

0개의 댓글