[Android] RecyclerView

๐Ÿ’ก ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ RecyclerView์— ๋Œ€ํ•˜์—ฌ ๊ธฐ๋กํ•˜์˜€์Šต๋‹ˆ๋‹ค !

 

RecyclerView

  • Android์—์„œ ํฐ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ๋„์ž…๋œ ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•œ UI ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
  • ListView์˜ ํ›„์†์œผ๋กœ ๊ฐœ๋ฐœ๋˜์—ˆ์œผ๋ฉฐ, View๋ฅผ ์žฌํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

RecyclerView  |  Android Developers

 

RecyclerView  |  Android Developers

androidx.appsearch.builtintypes.properties

developer.android.com

 

ListView์™€ ์ฐจ์ด์ 

ViewHolder ํŒจํ„ด ๋‚ด์žฅ

  • ListView์—์„œ๋Š” ViewHolder ํŒจํ„ด์ด ํ•„์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ RecyclerView์—์„œ๋Š” ์ด ํŒจํ„ด์ด ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณต๋˜๋ฉฐ ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ์ค„์ด๊ณ  ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ์—ฐํ•œ LayoutManager

  • ListView๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ธ๋กœ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ, RecyclerView๋Š” LayoutManager๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ๋ ˆ์ด์•„์›ƒ์„ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Item Animation & Decorator

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์•„์ดํ…œ ์ถ”๊ฐ€, ์‚ญ์ œ, ์ด๋™ ์‹œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ItemDecoration ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๊ตฌ๋ถ„์„ , ์—ฌ๋ฐฑ ๋“ฑ ๋‹ค์–‘ํ•œ ์•„์ดํ…œ ๊ฐ„์˜ ๋ฐ์ฝ”๋ ˆ์ด์…˜์„ ์œ ์—ฐํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ฑ๋Šฅ ํ–ฅ์ƒ

  • ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์ฒ˜๋ฆฌ

  • ListView์—์„œ๋Š” notifyDataSetChanged()๋ฅผ ํ†ตํ•ด์„œ ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•ด์•ผ ํ–ˆ์ง€๋งŒ, RecyclerView์—์„œ๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ตฌํ˜„

ViewHolder

  • Adapter๊ฐ€ RecyclerView์˜ ๊ฐœ๋ณ„ ํ•ญ๋ชฉ์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๊ธฐ๋Šฅ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • findViewById ํ˜ธ์ถœ์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val textView: TextView = itemView.findViewById(R.id.textView)
}

Adapter

  • Adapter๋Š” ๋ฐ์ดํ„ฐ์™€ RecyclerView๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ , ๊ฐ ํ•ญ๋ชฉ์˜ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ๊ณผ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
class MyAdapter(private val items: List<Item>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    // onCreateViewHolder - ๊ฐ ํ•ญ๋ชฉ์˜ ๋ ˆ์ด์•„์›ƒ์„ ์ดˆ๊ธฐํ™”
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
        return MyViewHolder(view)
    }

    // onBindViewHolder - ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.textView.text = items[position].text
    }

    // getItemCount - ํ•ญ๋ชฉ ์ˆ˜ ๋ฐ˜ํ™˜
    override fun getItemCount(): Int {
        return items.size
    }
}

  • ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ๋ฆฌ์ŠคํŠธ๋ฅผ ์–ด๋Œ‘ํ„ฐ์™€ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ ๋ทฐ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
// LayoutManager ์„ค์ • (์„ธ๋กœ ๋ฆฌ์ŠคํŠธ)
recyclerView.layoutManager = LinearLayoutManager(this)

// Adapter ์„ค์ •
val items = listOf(Item("Item 1"), Item("Item 2"), Item("Item 3"))
recyclerView.adapter = MyAdapter(items)
  • ์ฃผ์˜ํ•  ์ ์€ xml์ด๋‚˜ Programmatically ์ฝ”๋“œ ์ƒ์—์„œ layoutManager๋ฅผ ๋ฐ˜๋“œ์‹œ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

LayoutManager

  • RecyclerView์˜ ํ•ญ๋ชฉ ๋ฐฐ์น˜๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ปค์Šคํ…€ ๋ ˆ์ด์•„์›ƒ ๋งค๋‹ˆ์ €๋„ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

DataChange

  • RecyclerView์—์„œ๋Š” Adapter์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด์„œ ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜์ง€ ์•Š๊ณ ๋„ ํŠน์ • ํ•ญ๋ชฉ์ด๋‚˜ ๋ฒ”์œ„์˜ ๋ฐ์ดํ„ฐ๋งŒ ์—…๋ฐ์ดํŠธ, ์ถ”๊ฐ€, ์‚ญ์ œ, ์ด๋™ ๋“ฑ์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ ์„ฑ๋Šฅ ๋‚ญ๋น„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์•ฑ์˜ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

notifyDataSetChanged()

  • ๋ฐ์ดํ„ฐ ์ „์ฒด๊ฐ€ ๋ณ€๊ฒฝ ๋จ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  • ์ „์ฒด๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„ํšจ์œจ์ ์ด๋ฉฐ, ์ฃผ๋กœ ํฐ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

notifyItemChanged(int position)

  • ํŠน์ • ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ์œ„์น˜์˜ ์•„์ดํ…œ๋งŒ ๋‹ค์‹œ ๊ทธ๋ ค์ง€๊ธฐ ๋•Œ๋ฌธ์— ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
  • ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์•„๋ ˆ์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • notifyItemInserted(int position)
    • notifyItemRemoved(int position)

notifyItemRangeChange(int positionStart, int itemCount)

  • ํŠน์ • ๋ฒ”์œ„์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  • notifyItemRangeChange(3,5)๋ผ๋ฉด 3๋ฒˆ์งธ ์•„์ดํ…œ๋ถ€ํ„ฐ 5๊ฐœ์˜ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  • ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • notifyItemRangeInserted(int positionStart, int itemCount)
    • notifyItemRangeRemoved(int positionStart, int itemCount)