0101011001010111

Android _ RecyclerView 의 Adapter 본문

Kotlin/[스스로]Kotlin&안드로이드

Android _ RecyclerView 의 Adapter

[진주] 2023. 9. 13. 17:18
728x90
반응형

package com.example.recyclerview_update

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {

    interface ItemClick {
        fun onClick(view : View, position : Int)
    }

    var itemClick : ItemClick? = null

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

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.itemView.setOnClickListener {
            itemClick?.onClick(it, position)
        }
        holder.iconImageView.setImageResource(mItems[position].aIcon)
        holder.name.text = mItems[position].aName
        holder.age.text = mItems[position].aAge
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

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

    inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {
        val iconImageView = binding.iconItem
        val name = binding.textItem1
        val age = binding.textItem2
    }
}

 

▼ 어댑터에 대한 더 자세한 설명 

 

Adapter는 데이터를 쓸 수 있게 가공해주는 역할!

 

예를들면, 어댑터는 

 

이런 여행용 어댑터를 생각하면 편한데, 

데이터(=전기)를 받아와, 110v , 220v 든 내가 원하는 것에 맞춰서 변경해준다.

 

즉, 

 

우리가 item이라는 틀을 만들었음. 

아까 2번에서 

2. 아이템 레이아웃 생성 :  아이템 하나의 레이아웃을 작성합니다.

원하는 대로 만들어보기!

이렇게 만들어 주었는데, 어댑터를 통해서, 들어갈 이미지와 텍스트 들을 딱딱 가공해서 쇽쇽 넣어주는 역할을 하는게 어댑터이다 !! (가공!!)

 

즉, 정제되지 않은 데이터를 어댑터를 통과하면 딱 맞게 들어갈 수 있다 . 

class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {

어댑터는 RecyclerView의 Adapter를 상속받아 만들어진다.

 

어댑터의 구조는 항상 똑같으니 복붙하면 된다. 

 

 

그리고, 중요한 우리가 바꿔야 할 부분은 

크게 3가지가 있다.

 

첫번째 , Holder 

inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {
    val iconImageView = binding.iconItem
    val name = binding.textItem1
    val age = binding.textItem2

 

 

 

 

두번째, onCreateViewHolder

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

 

 

 

세번째, onBindViewHolder

override fun onBindViewHolder(holder: Holder, position: Int) {
    holder.itemView.setOnClickListener {
        itemClick?.onClick(it, position)
    }
    holder.iconImageView.setImageResource(mItems[position].aIcon)
    holder.name.text = mItems[position].aName
    holder.age.text = mItems[position].aAge
}

 

이 3가지만 바꾸면 된다.

 

 

override fun getItemId(position: Int): Long {
    return position.toLong()
}

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

이 부분은 어딜가나 똑같고, 

 

interface ItemClick {
    fun onClick(view : View, position : Int)
}

var itemClick : ItemClick? = null

 

인터페이스 아이템 클릭 부분은 클릭 때문에 따로 만들어놓은 거기 때문에 사실 어댑터와 상관 없다.

지금은 Adapter만 얘기하고 있는거임.  그래서 상관X

 

 


결국 위 3개만 바꾸면 되는데, 

하나하나 설명하도록 하겠다.

 

 

첫번째 , Holder 

 

inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {
    val iconImageView = binding.iconItem
    val name = binding.textItem1
    val age = binding.textItem2
}

홀더는 , 

우리가 하나의 아이템을 만들기 위해서 데이터 클래스를 만들었잖아요 ? 

그러려면 이 하나의 아이템을 클래스화 시켜야합니다. 

 

그래서 그걸 만드려는게 이 Holder라는 친구임.

이 홀더 하나가 계속해서 재사용 된다고 보면 된다.

이 홀더 안에 Bella라는 데이터를 넣고,

그다음 Charlie라는 데이터를 넣고

 

그게 쌓여서 리스트가 된다.

 

 

현재 이제 뷰바인딩을 쓰기로 했으니, 

(val binding: ItemRecyclerviewBinding)

 

이렇게 된건데 연결된 화면은, 

이 xml의 이름이 item_recyclerview.xml

아이템 틀로 만든 이것이다.

이 아이템 xml의 이름이 item_recyclerview.xml이기 때문에 위에 들어가는 이름이 ItemRecyclerviewBinding이 된것이다.(자동생성이름)

만약 이름을 바꾸면 다르게 생성됨.

 

이렇게 바인딩으로 아이템 틀을 받아와서 ,

이렇게 연결할 변수명을 짓고, 아이템에서 뭐랑 연결할건지 binding.xml의 아이템id를 적어주면 연결이 된다.

 

 

 

어댑터가 실행되었을 때, 가장먼저 이 홀더가 먼저 만들어 진다.

그다음, 두번째 onCreateViewHolder가 이 홀더를 가장 먼저 실행시킨다. 

 

 

두번째, onCreateViewHolder

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

▲onCreateviewHolder는 누가 실행시키냐면, 안드로이디 시스템 내에서 RecyclerView가 얘를 호출하는거다. (우리가 부르는거 아님)

그럼 이런게 있다 라고만 알고 있음 되고, 

 

onCreateviewHolder는, 

return Holder(binding)

 

홀더를 호출하는데, 

홀더는 xml과 아이디만 연결해준 상태다. 

 

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {

parent는 부모뷰를 의미한다.

현재 이 아이템의 부모 뷰는 리사이클러 뷰이다. 

: Holder로 홀더 상속 받았다.

 

val binding = ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)

이제 바인딩을 하나 만드는데, 

똑같이, 

val binding = xmlBinding.inflate

 

여기서 .inflate는 xml이 실제 단말에서 뷰로 전환되는 걸 inflate라고 한다.

 

(LayoutInflater.from(parent.context), parent, false)

(parent 밑으로 집어넣는다, 근데 바로 붙이진 않는다) //코드내용을 해석하자면 대강 이런뜻

 

이 뒷부분 고정임 . 외우는거 X 그냥 같다 붙이는거! 

 

 


자 여기까지 했다면 어댑터는 구성이 다 되었다.

 

그럼 이제 할건, 데이터가 들어옴에 따라 업데이트를 시켜줘야 하는데, 

그 역할을 

MainActivity

메인에서보면 이렇게 MyItem이라는 걸 만들어둔걸 데이터 원본 준비할때 이미지, 이름, 나이 이렇게 넣은 더미데이터가 있고, 

 

 

binding.recycleView.apater = MyAdapter(dataList)

 

val adapter = MyAdapter(dataList)

binding.recycleView.adapter = adapter

binding.recycleView.layoutManager - LinearLayoutManager(this)

 

▲ 이부분 그대로 복사해서 써준다.

 

 

우리가 지금까지 한 홀더와 온크래이트뷰홀더는 , 이제 틀안에 뭘 넣을건지 연결시키는 것들을 했는데,

 

이제 이 더미데이터의 내용을 하나씩 줘봐! 

라고 할 것이다 

뷰를 쭈르르르륵 만들어야하기 때문에, 

 

지금 폰 화면에 홀더를 몇개정도 실행시킬수 있을 거 같아 줘봐! 라고 하면, (시스템에서 하는거임 이건) 

 

 

세번째, onBindViewHolder

override fun onBindViewHolder(holder: Holder, position: Int) {
    holder.itemView.setOnClickListener {
        itemClick?.onClick(it, position)
    }
    holder.iconImageView.setImageResource(mItems[position].aIcon)
    holder.name.text = mItems[position].aName
    holder.age.text = mItems[position].aAge
}

이 온바인드뷰홀더가 8번 실행된다. (데이터 쓴 순서대로 실행)

 

코드를 분석해보자면, 

holder.itemView.setOnClickListener {
    itemClick?.onClick(it, position)
}

이 부분은 클릭때문에 있는거라 일단 넘어가도록 하겠다.

 

 

 

holder.iconImageView.setImageResource(mItems[position].aIcon)
holder.name.text = mItems[position].aName
holder.age.text = mItems[position].aAge

여기서 mItems은 아까 더미데이터. 

position은 0~ 7번까지 들어갈텐데.

0번은, 

Bella 부분이 된다.

 

그럼 onBindViewHolder의 다시 첫줄을 보면, 

override fun onBindViewHolder(holder: Holder, position: Int) {

 

괄호 안에, holder: Holder  // 우리가 아까 만들었던 홀더, position은 : 0번째를 호출한다. 라는 의미

그럼 position 0번은 벨라의 데이터이고, 

벨라의 사진인 sample_0과, 이름 : bella , 나이 1살 이 차례로 호출되어 들어간다.

holder.iconImageView.setImageResource(mItems[position].aIcon)
holder.name.text = mItems[position].aName
holder.age.text = mItems[position].aAge

 

holder.iconImageView.setImageResource(mItems[position].aIcon)

 

holder(아까만든홀더). iconImageView(아까 홀더에 이 이름으로 변수를 줬다.).setImageResource(이미지 불러올때하는거)

(mItems[position].aIcon)

 

name이랑 age도 마찬가지.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형