RecyclerView에 View Binding 적용하기

이번 포스팅에서는 RecyclerView에 View Binding을 적용하는 법에 대해 알아보도록 하겠습니다.

View Binding을 사용해야 하는 이유나 그 장점에 대해서는 findViewById 대신 View Binding 사용하기 포스팅과 유튜브 강의를 참조하시고 이번 포스팅에선 변환하는 방법에 대해서만 설명하도록 하겠습니다.

이번 포스팅에서 변환에 사용한 프로젝트는 앱에서 RecyclerView 사용하기 포스팅에서 작성한 것을 사용하도록 하겠습니다.

코드 작성

View Binding 활성화

우선은 gradle에서 kotlin-android-extensions 플러그인을 삭제하고 View Binding을 활성화합니다.

1
2
3
4
5
6
7
plugins {
-    id 'kotlin-android-extensions'
}

android {
+    buildFeatures.viewBinding true
}

메인액티비티 수정

다음은 메인액티비티를 수정해줍니다. View Binding을 활성화하는 순간 생기는 ActivityMainBinding 클래스를 초기화하여 binding이라는 인스턴스로 사용합니다. 기존의 RecyclerView의 프로퍼티는 binding.recyclerView로 접근하여 설정합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val dataSet: ArrayList<List<String>> = arrayListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
-        setContentView(R.layout.activity_main)

-        addData()
-
-        recycler_view.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
-//        recycler_view.layoutManager = GridLayoutManager(this, 2)
-
-        recycler_view.adapter = RecyclerViewAdapter(dataSet)
-        recycler_view.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL))

+        binding = ActivityMainBinding.inflate(layoutInflater)
+        setContentView(binding.root)
+        addData()
+        binding.recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+        binding.recyclerView.adapter = RecyclerViewAdapter(dataSet)
+        binding.recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
    }

    private fun addData() {
        for (i in 0..99) {
            dataSet.add(listOf("$i th main", "$i th sub"))
        }
    }
}

Recyclerview 어댑터 수정

onCreateViewHolder에서 뷰를 만들 때 ListItemBinding 클래스로 만들어지는 binding 인스턴스를 사용하도록 변경하여줍니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class RecyclerViewAdapter(private val dataSet: ArrayList<List<String>>): RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): ViewHolder {
-        val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
-        return ViewHolder(view)
+        val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+        return ViewHolder(binding)
    }

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

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

ViewHolder 수정

기존의 ViewHolder에서는 뷰를 받아와서 정의하고 그걸 데이터와 연결하는 작업이 필요했는데, View Binding에서는 binding 인스턴스가 생성되는순간 자동으로 뷰를 binding의 프로퍼티로 접근할 수 있기 때문에 이 코드가 필요없게 됩니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class RecyclerViewAdapter(private val dataSet: ArrayList<List<String>>): RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {

-    class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
-        private val tvMain: TextView = view.tv_main
-        private val tvSub: TextView = view.tv_sub
-
-        fun bind(data:List<String>) {
-            tvMain.text = data[0]
-            tvSub.text = data[1]
-        }
-    }
+    class ViewHolder(private val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root) {
+        fun bind(data:List<String>) {
+            binding.tvMain.text = data[0]
+            binding.tvSub.text = data[1]
+        }
    }
}

이렇게 해서 RecyclerView에 View Binding을 적용하는 방법에 대해 알아보았습니다.

Built with Hugo
Theme Stack designed by Jimmy