RecyclerView란.

두리두두·2024년 5월 1일

Android

목록 보기
11/25

리사이클러뷰.를 알아보자

리사이클러뷰란

  • 이름 그대로 재사용이 가능한 뷰.
  • 일반 리스트뷰는 필요한만큼 계속 재생성이 되는데 리사이클러뷰는 보여지는 부분만 생성되고 스크롤 등의 이벤트로 추가로 보여져야할 때는 이미 만들어진 뷰를 재사용한다.
  • 카카오톡 채팅 리스트 등 동일한 형태의 뷰를 반복해서 보여줘야할 때 사용
  • RecyclerView는 View 갯수가 한정되어 있기에, 앱 구동 시 메모리 사용량을 줄일 수 있다.

구성요소

  • 크게 adapterlayoutManager가 필요하다. 근데 체감되는건 어답터가 중요하고 레이아웃매니저는 약간 조정만 하는 느낌?
  • 메인액티비티에서 얘네 둘을 리사이클러뷰에 적용하니 과정을 쭈욱 봐보자

1. 메인 레이아웃.xml

  • 리사이클러뷰를 쓸 화면
  • 메인액티비티에서 사용, 여기에 리사이클러뷰를 쓸 공간 지정하여 <RecyclerView> 태그로 지정
  • 리사이클러뷰의 id는 recycler_view
<?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/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
</FrameLayout>

2. 개별 리사이클러뷰에 나올 레이아웃.xml

  • 텍스트와 이미지를 보여줄 것이기 때문에 MaterialCardView안에 LinearLayoutView를 넣고 TextViewIamgeView 사용
  • 텍스트뷰는 item_title, 이미지뷰는 item_image 를 id로 사용
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >
    <TextView
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?attr/textAppearanceHeadline6"/>
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="194dp"
        android:id="@+id/item_image"
        android:importantForAccessibility="no"
        android:scaleType="centerCrop" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

3. 어답터.kt

  • 리사이클러뷰의 구성요소와 거기 들어갈 데이터를 연결하는 객체
  • RecyclerView.adpater라는 객체를 반환한다.
  • 연결시킬 데이터를 인자로 받는 클래스이다.

3-1). 뷰홀더 구현

  • 뷰홀더를 생성해서 거기에 레이아웃과 값을 채우는 과정으로, 뷰홀더를 만들 수 있는 객체를 준비해야한다.
 //  ViewHolder는 RecyclerView의 단일 목록 항목 뷰를 나타내며 가능한 경우 재사용할 수 있습니다.
    class ItemViewHolder(private val view: View):RecyclerView.ViewHolder(view){
        val textView: TextView = view.findViewById(R.id.item_title)
        val imageView: ImageView = view.findViewById(R.id.item_image)
    }

3-2). 바인딩

  • 필수로 사용되는 함수 3개
    1) onCreateViewHolder()
    - 이름 그대로,, 뷰홀더 객체 레이아웃을 만드는 함수
    - 데이터와 뷰를 매치해서 ViewHolder()객체를 반환한다.

       // 뷰 홀더는 단일 목록 항목 뷰를 나타냅니다.
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
         // create a new view
         val adapterLayout = LayoutInflater.from(parent.context)
             .inflate(R.layout.list_item, parent, false)
    
         return ItemViewHolder(adapterLayout)
     }

    2) getItemCount()
    - 인자로 받은 데이터셋의 개수 반환

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

    3) onBindViewHolder(holder: ItemViewHolder, position: Int)
    - 인자로 뷰홀더 객체와 인덱스값 정수를 받는다.
    - 전달 받은, 레이아웃이 세팅되어있는 뷰홀더에 각 데이터를 매핑한다.

        override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
         val item = dataset[position]
    
         // getString()은 Resources 클래스의 메서드이며, context를 통해 Resources 클래스의 인스턴스를 가져올 수 있습니다.
         holder.textView.text = context.resources.getString(item.stringResourceId)
         holder.imageView.setImageResource(item.imageResourceId)
     }

4. 메인액티비티.kt

  • 리사이클러뷰를 불러와서 만들고, 어답터 적용 (리사이클러뷰와 데이터를 매개변수로 넘겨준다)
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val myDataSet = Datasource().loadAffirmation()
        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        recyclerView.adapter = ItemAdapter(this, myDataSet)
        recyclerView.setHasFixedSize(true)
    }
}

5.레이아웃 매니저

  • 레이아웃 매니저는 xml에서 설정할 수도 있고, 메인액티비티에서 리사이클러뷰에 어답터 붙일 때 설정할 수도 있다.
    5-1) xml에서 설정
  • app:layoutManager로 설정
<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

5-2) kt파일에서 설정

  • 리사이클러뷰.layoutManager = LinearLayoutManager(this)로 설정
  // Recycle View의 Item 배치설정
        recyclerView.layoutManager = LinearLayoutManager(this)

정리

  • 리사이클러뷰를 쓰려면,,, 리사이클러뷰를 쓸 화면에서 태그로 공간을 만들어주고, 디테일 레이아웃은 따로 만든다.
  • 그 후에 어답터에서 뷰홀더를 만들고, 뷰홀더에서 디테일 레이아웃의 각 뷰들을 지정한다.
  • 어답터 onCreateViewHolder 함수에서 디테일 레이아웃을 전달받고, 뷰홀더 객체에 넣어준다. (그럼 뷰홀더 객체에서 알아서 각 뷰를 설정) 뷰홀더 객체와 onCreateViewHolder 함수의 역할에 대해 좀 헷갈렸는데 객체는 그냥 따로 만들어둔 것 뿐이고, 거기에 필요한 레이아웃을 받아서 넣어주는게 onCreateViewHolder 함수. 역할을 나눠둔 것
  • 그리고 onBindViewHolder에서 만들어진 객체의 정보를 매핑한다.
  • 이걸 할 수 있게 하는게 메인 액티비티에서 리사이클러뷰 만들고, 데이터들과 어답터를 붙여주는 과정

실습 결과

profile
야금야금 앱 개발자

0개의 댓글