๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ๊ฐœ๋ฐœ์ž ์ด์•ผ๊ธฐ/์•ˆ๋“œ๋กœ์ด๋“œ ์‚ฝ์งˆ๊ธฐ

kotlin-android-extensions ๋ฅผ ๊ฑท์–ด๋‚ด์ž. ๊ฑท์–ด๋‚ด์ž!

by ์ •์„ ํ•œ 2024. 3. 22.
728x90
๋ฐ˜์‘ํ˜•

์ด๋ฏธ ์ง€์› ์ข…๋ฃŒ๋œ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด์ง€๋งŒ, ์•„์ง ์ œ๊ฐ€ ๋“ค๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์‚ด์•„ ์ˆจ ์‰ฌ๋Š” ์ด ์นœ๊ตฌ์™€ ํ•œ๋ฒˆ ์ ˆ๊ต๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ € gradle(:app)ํŒŒ์ผ ๋‚ด์˜ plugins์— ์ ์šฉ๋˜์–ด ์žˆ๋Š” 'kotlin-android-extensions'์„ ์‚ญ์ œํ•˜๊ณ , buildFeature ๋‚ด๋ถ€์— viewBinding์ด ํ™œ์„ฑํ™”๋˜์–ด์žˆ์ง€ ์•Š์œผ๋ฉด true๋กœ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋“ค๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์—๋Š” ์ด๋ฏธ viewBinding์ด ์ ์šฉ๋˜์–ด ์žˆ๊ณ , synthetic๊ธฐ๋Šฅ์„ ๋ ˆ๊ฑฐ์‹œ๋กœ ํ˜ผ์šฉํ•˜์—ฌ ์“ฐ๊ณ  ์žˆ๋˜ ํ˜•ํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ ํ™œ์„ฑํ™”๋Š” ๋˜์–ด์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
kotlin-android-extensions์„ ํ†ตํ•ด ๊ธฐ ์ ์šฉ๋œ ์„œ๋น„์Šค๋ฅผ ๋ณด๋ฉด, kotlin์˜ synthetic ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ viewBinding์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•œ ๋ชจ์Šต๋“ค์„ ๋ณผ ์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋Š” kotlin-android-extension์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์œผ๋กœ ํ•ด๋‹น ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์‚ญ์ œ๋˜๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (๋นŒ๋“œ์กฐ์ฐจ ๋Œ์•„๊ฐ€์ง€ ์•Š์•„์„œ ์˜ค๋ฅ˜ ๋‚˜๋Š” ํฌ์ธํŠธ๋Š” ๋ช…ํ™•ํ•˜๊ฒŒ android studio์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”)
๋”ฐ๋ผ์„œ ๊ธฐ ์ ์šฉ๋œ viewBinding ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ์ˆœ๊ฐ„์ด ์ฐพ์•„์˜ค๊ฒŒ ๋˜๋Š” ๊ฒƒ์ธ๋ฐ, ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ view๋ฅผ ๊ฐ์ฒดํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์ด 3๊ฐ€์ง€ ์ •๋„์˜€์Šต๋‹ˆ๋‹ค. ์ด์ œ๋Š” 2๊ฐ€์ง€๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”.

  1. findViewById() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ View๋ฅผ ๊ฐ์ฒดํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•
  2. kotlin-android-extension, synthetic ์„ ์‚ฌ์šฉํ•˜์—ฌ View๋ฅผ ๊ฐ์ฒดํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•
  3. ๋งˆ์ง€๋ง‰์œผ๋กœ viewBinding์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

์—ฌ๊ธฐ์„œ 2๋ฒˆ์˜ ํ•ญ๋ชฉ์€ ์ด์ œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ์„œ๋น„์Šค ์ค‘์ธ ์ฝ”๋“œ์— synthetic์„ importํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๋ฉด, ์ผ๋‹จ ํ™•์ธํ•ด ๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ €๋„ ์•Œ๊ณ  ์‹ถ์ง€ ์•Š์•˜์–ด์š”...ใ…Ž

  • ์ฐธ๊ณ ๋กœ ๋‚ด์šฉ์„ ๋ถ™์ด์ž๋ฉด, synthetic์€ kotlin ์ฝ”๋“œ ์™ธ๋ถ€์˜ ์š”์†Œ (view, layout, ...etc)์™€์˜ ์กฐํ•ฉ์„ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง„ property๋“ค์„ ์นญํ•˜๋Š” ๊ฒƒ์œผ๋กœ kotlin-android-extensions ๋‚ด์—๋Š” Activity, Fragment, View ํด๋ž˜์Šค ํ˜น์€ ์ž์‹ ํด๋ž˜์Šค๋“ค์—์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ณ  XML ๋‚ด์— ์ •์˜๋œ ๋ทฐ์˜ ์ธ์Šคํ„ด์Šค์— ๋ฐ”๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ binding์ฒ˜๋ฆฌ ์—†์ด id์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ–ˆ์—ˆ๋˜ ๊ฒƒ์ด์ฃ . ์ž์ฒด์ ์œผ๋กœ findViewById()๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ฐ์ฒดํ™” ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

์ด์   findViewById(), viewBidning์„ ํ†ตํ•ด์„œ View๋ฅผ ๊ฐ์ฒดํ™” ํ•˜๋ฉด ๋˜๋Š”๋ฐ, ์‚ฌ์‹ค findViewById()๋Š” view๋งˆ๋‹ค ์ž‘์„ฑํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์˜จ ์ฒœ์ง€์— findViewById()๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฑธ boilerplate๋ผ๊ณ ๋„ ํ•˜๋Š”๋ฐ,, ๋ชจ๋ฅด๊ฒ ๊ณ ,, ๊ทธ๋ƒฅ ์ผ๋‹จ ๋•์ง€๋•์ง€ ๋˜‘๊ฐ™์€ ๋ฌธ์ž์—ด์ด ๋ฐ˜๋ณต๋˜์–ด ์žˆ๋‹ค? ๋ˆˆ์— ๋ณด๊ธฐ ์˜ˆ์˜์ง€ ์•Š๋‹ค...๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ๋ชป์ƒ๊ฒผ์ž–์•„์š”.
๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ฝ”๋“œ ๊ฐœ์„ ์„ viewBinding์œผ๋กœ ํ•ด๋ณผํ…๋ฐ, ๊ธฐ์กด์— kotlin synthetic์„ ์‚ฌ์šฉํ•˜์—ฌ viewBinding์„ ๊ตฌํ˜„ํ–ˆ๋˜ ์ฝ”๋“œ๋Š” ์•„๋ž˜์˜ ๊ตฌํ˜„์œผ๋กœ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.
์‚ฌ์‹ค viewBinding์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•˜๊ฒŒ ํ•ด์ค€ ๊ฒƒ์ด synthetic์˜ ๊ธฐ๋Šฅ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒƒ์€ ์—†์ง€๋งŒ
์ฃผ๋กœ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒƒ์€ view๊ฐ์ฒด ์ž์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋˜ ๊ฒƒ์„ binding.getRoot()๋กœ View๋ฅผ ๊ฐ์ฒดํ™”ํ•ด์„œ ๋„˜๊ฒจ์ฃผ๋Š” ๋ถ€๋ถ„์œผ๋กœ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ด ์ฝ”๋“œ์—์„œ๋Š” ViewHolder์˜ ์ƒ์„ฑ ๋ถ€๋ถ„์ด ํฌ๊ฒŒ ๋ฐ”๋€Œ์—ˆ๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์•„์š”.

import kotlinx.android.synthetic.main.[layoutName].view.*

class PagerRecyclerAdapter(private val itemList: MutableList<[DataModel]>) 
: RecyclerView.Adapter<PagerRecyclerAdapter.PagerViewHolder>() {

    inner class PagerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bind(item: [View]) {
            Glide.with(itemView.context)
                .load([item.URL])
                .into(itemView.[id])
            }
        }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagerViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(
            R.layout.[layoutName],
            parent,
            false
        )
        return PagerViewHolder(view)
    }

    override fun onBindViewHolder(holder: PagerViewHolder, position: Int) {
        holder.bind(itemList[position])
    }

    override fun getItemCount(): Int = itemList.size
}

์ด ์•„๋ž˜๊ฐ€ viewBinding์„ ํ†ตํ•œ RecyclerViewAdapter์˜ ๊ตฌํ˜„์ธ๋ฐ์š”. ์œ„ ์ฝ”๋“œ์—์„œ ๋ฐ”๋€ ์ ๋“ค์„ ํ•œ๋ฒˆ ๋ณด์‹œ๋ฉด ๊ฐ์ด ์˜ค์‹ค ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import [PackageName].databinding.[ClassName]Binding

class PagerRecyclerAdapter(private val itemList: MutableList<[DataModel]>)
    : RecyclerView.Adapter<PagerRecyclerAdapter.PagerViewHolder>() {

    inner class PagerViewHolder(private val binding: [ClassName]Binding)
        : RecyclerView.ViewHolder(binding) {

        fun bind(item: [View]) {
            Glide.with(binding)
                .load([item.URL])
                .into(binding.[id])
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagerViewHolder {
        val binding = [ClassName]Binding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return PagerViewHolder(binding.root)
    }
    override fun onBindViewHolder(holder: PagerViewHolder, position: Int) {
        holder.bind(itemList[position])
    }

    override fun getItemCount(): Int = itemList.size
}

binding.root์˜ ํ•จ์ˆ˜ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. View๋ฅผ return ํ•ด ์ฃผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜๊ฐ€ ์žˆ์–ด์š”.

/**
    * Returns the outermost View in the layout file associated with the Binding. If this
    * binding is for a merge layout file, this will return the first root in the merge tag.
    *
    * @return the outermost View in the layout file associated with the Binding.
    */
@NonNull
@Override
public View getRoot() {
    return mRoot;
}

์ด ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด, PagerViewHolder innerClass์— binding ๋ณ€์ˆ˜๋กœ View ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด, ๊ทธ ViewBinding์„ ํ†ตํ•ด id๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ทธ๋Ÿฐ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.
์ž์ž˜ ์ž์ž˜ํ•˜๊ฒŒ ์ฝ”๋“œ ์ „๋ฐ˜์— ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ๋‚ด์šฉ๋“ค์ด๊ณ  ๋˜ ์ด ๋ถ€๋ถ„์ด ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ทธ๋ฆฌ๊ณ , ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ๋‚ด์šฉ๋“ค์ด๋ผ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋„ ์ ์ง€ ์•Š๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธฐ๊ณค ํ–ˆ๋Š”๋ฐ์š”. ์–ด์ฐŒ์–ด์ฐŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ ๋„ฃ์–ด๊ฐ€๋ฉฐ ๋Œ€์‘์„ ํ•˜๊ธฐ๋Š” ํ–ˆ๋„ค์š” ใ…Žใ…Ž
์ด ํฌ์ŠคํŒ…์˜ ๋ชฉ์ ์€ android-kotlin-extensions์„ ๊ฑท์–ด๋‚ด๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ์ˆ ์ ์ธ ๋‚ด์šฉ๋“ค์€ ๋‹ค๋ฅธ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ฃจ์–ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ฐธ๊ณ ๋ฌธ์„œ

Kotlin ํ•ฉ์„ฑ์—์„œ Jetpack ๋ทฐ ๊ฒฐํ•ฉ์œผ๋กœ ์ด์ „  |  Android ๊ฐœ๋ฐœ์ž  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Kotlin ํ•ฉ์„ฑ์—์„œ Jetpack ๋ทฐ ๊ฒฐํ•ฉ์œผ๋กœ ์ด์ „ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. Kotlin Android ํ™•

developer.android.com

 

728x90
๋ฐ˜์‘ํ˜•