앞서 viewBinding에 대해서 알아보았다. viewBinding은 xml의 id를 activity에서 참조 가능하게 하는 것이었다.
그렇다면 dataBinding은 무엇일까? 🤔
dataBinding은 viewBindg과 반대로 xml에서 data를 결합해서 사용 가능하도록 하는 것이다. 여기서 data는 viewModel, data class, 변수 등이 모두 될 수 있다.
추가로 dataBinding은 viewBinding의 기능을 포함하고 있다. 즉 activity에서는 xml참조가 가능하고 xml에서는 activity를 거치지 않고 viewModel의 데이터를 받아올 수 있다.
MVC 패턴에서는 Activity가 Controller로써 많은 일을 하고 있었다.
하지만 MVVM 패턴에서는 이 Activity의 일을 나눠가지고자 ViewModel이 등장하였고 Activity는 프레젠테이션 로직(눈에 보이는)을, ViewModel은 비지니스 로직(데이터 관리)을 하도록 역할을 분담하였다.
ViewModel의 등장으로 activity는 일이 줄었지만 XML과 ViewModel의 데이터를 연결시켜줘야하는 중간다리 역할이 생기게 되었다.
이 중간다리 역할을 좀 더 줄여 XML에서 ViewModel의 데이터를 바로 받아 올 수 있도록 해주는 것이 DataBinding이다.
buildFeatures {
dataBinding = true
}
ViewModel type의 파일 필요
class MainActivityViewModel : ViewModel(){}
XML에서 dataBinding형태로 바꿔 주고 (해당 DataBinding 파일 생성)
data 영역에 참조할 viewModel을 선언해준다.
name은 사용할 변수 이름이고, type은 결합할 파일(위치포함)이다.
viewModel뿐만 아니라 다른 데이터도 여러개 선언이 가능하다.
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="(viewModel파일 이름 위치).MainActivityViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
activity에서 XML databinding 선언되어 있는 변수에 실제 데이터를 mapping 시켜줘야 한다.
viewModel의 경우 아래와 같이 activity에서 선언한 viewModel(koin 사용)과 XML에서 선언한 viewModel을 mapping 시켜준다.
class MainActivity : AppCompatActivity() {
val viewModel by viewModel<MainActivityViewModel>()
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this , R.layout.activity_home)
binding.lifecycleOwner = this
binding.viewModel = viewModel
}
위 준비 과정을 마쳤으면 이제 XML에서 DataBinding이 가능하다.
var textValue = "textValue"
var textValue2 = "textValue2"
위 준비과정에서 결합시킨 viewModel 파일에서 선언된 변수가 존재할 때,
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="(viewModel파일 이름 위치).MainActivityViewModel" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.textValue}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.textValue2}"/>
</LinearLayout>
</layout>
xml에서 연결한 viewModel의 값을 @{}형태로 사용이 가능하다.
위 예시는 viewModel 파일 하나를 결합한 것이고 viewModel 파일 뿐만 아니라 여러 모델도 결합이 가능하다.
View를 import 해서 표현식에서 visibility를 활용할 수 있다.
<data>
<import type="android.view.View" />
</data>
ViewModel
var textValue = "textValue"
var textValue2 = "textValue2"
var count = 3
XML
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="(viewModel파일 이름 위치).MainActivityViewModel" />
<import type="android.view.View" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.count == 3 ? viewModel.textValue1 : viewModel.textValue2}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="count가 3이면 보입니다."
android:visibility = "@{viewModel.count == 3 ? View.VISIBLE : View.GONE}"/>
</LinearLayout>
</layout>