Android/Architecture

DataBinding vs ViewBinding

Seoplee 2021. 11. 20. 01:27

DataBinding과 ViewBinding에 대한 기록

 

둘 다 모두 뷰를 직접 참조하게 해주는 binding class를 제공한다.

 

Databinding 혹은 Viewbinding을 적용하지 않으면 자바 및 코틀린 전부 findViewById라는 함수를 이용해서 view를 객체화 하여 사용한다

 

val Btn = findViewById<Button>(R.id.Button_id)

(이전에는 kotlin에서는 확장함수를 통해 findViewById없이 뷰의 이름만으로 바로 참조할 수 있었으나 deprecated 됨)

 

그러나 view component들이 많아질수록 findViewById를 계속해서 호출해야하므로 보일러플레이트가 발생하기 쉽고,

해당 view가 갖고있지 않는 id가 불러질 수 있어서 null exception에도 안전하지 못하다는 단점이 있다.

 

 

ViewBinding

탄생 배경 자체가 많은 사람들이 양방향 바인딩을 위해서가 아니라 단순히 view 참조를 빠르게 하기 위해 Databinding을 사용하는것을 보고 만들어졌다고 한다. (deprecated된 kotlin-extension 과 비슷한 용도로 쓰기위해.)

때문에 Databinding보다 빠르고, 사용방법또한 간결하다.

 

 

DataBinding

(사용방법에 대해서는  지난 포스팅 참고)

데이터 바인딩의 가장 큰 특장점으로는 양방향(two-way) 바인딩으로, View와 Model을 서로 엮어주는것인데, 쉽게 예시를 들자면(?) 사용자의 입력값을 바로 변수로 사용할 수 있다.

예를들어 안드로이드에서는 사용자가 입력하는 EditText를 LiveData로 저장해서 바로 뷰에 뿌려주는등의 방식으로 사용할 수 있다. 또한 BindingApdater를 작성해서 동적으로 UI를 관리할 수 있다.

 

 

MVVM구조에서 코드상의 큰 차이를 하나 생각해보자면, Viewbinding은 view단에서 관찰자를 통해 값을 항상 옵저빙하고 있어야 하지만, Databinding은 layout에서 binding expression을 이용할 수 있어서 관찰자를 두지 않아도 된다.

 

class MainViewModel: ViewModel() {

    private var textLiveData = MutableLiveData<String>()
    
    fun fetchData() {
    	textLiveData.value = "Hello, World"
    }
    
}

viewModel이 위와 같을 때

 

ViewBinding에서는

private fun initViews() {
    binding.showBtn.setOnClickListener {
        viewModel.fetchData()
    }
}
private fun observeData() {
	viewModel.numLiveData.observe(this) {
		binding.liveTextView.text = it
    }
}

View(Activity or Fragment)에서는 옵저빙하고있다가 view의 값을 직접 참조하여 바꾸거나 하는식으로 사용할 수 있다.

 

 

그러나 Databinding에서는

<layout 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">

      <data>
          <variable
              name="viewModel"
              type="com.example.packagename.MainViewModel"/>
      </data>

      <androidx.constraintlayout.widget.ConstraintLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context=".MainActivity">

          <TextView
              android:id="@+id/liveTextView"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@{viewModel.textLiveData}"
              app:layout_constraintBottom_toTopOf="@+id/showBtn"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent" />
              
          <Button
              android:id="@+id/showBtn"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Button"
              android:onClick="@{() -> viewModel.fetchData()}"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />

      </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

별도의 View에 코드를 작성하지 않고 위처럼 레이아웃 코드 내에서 데이터를 직접 가져오고 함수도 호출할 수 있게된다.