Android 생태계에서 이미 많이 사용되고 있는 DataBinding(데이터바인딩)은 간단하게 xml파일에 Data를 연결(binding)해서 사용할 수 있게 도와주며 Android JetPack 라이브러리의 하나의 기능 입니다.
즉, 데이터바인딩은 애플리케이션 로직과 레이아웃을 binding하는 데 필요한 글루 코드를 최소화합니다.
글루 코드란?
프로그램의 요구사항 구현에는 기여하지 않지만, 본래 호환성이 없는 부분끼리 결합하기 위해 작동하는 코드
-제타위키
내용이 이렇다 보니 findViewById를 사용하지 않아도 되며 보통 MVVM 패턴을 구현 할 때 "LiveData"와 함께 거의 필수적으로 사용합니다.
먼저 샘플용으로 만들어 볼 앱은 메인 화면의 TextView에 "Hello World!"가 표시되고 Button을 Click하게 되면 TextView에 "Hello Databinding!"이 출력 됩니다.
코드는 코틀린으로 진행합니다.
먼저 graddle에서 아래의 세팅의 추가 합니다.
kotlin-kapt plugin이 설치가 되어 있지 않다면 해당 세팅 값에 마우스를 올려두면 설치하라고 메시지가 뜨는데 설치해주시면 됩니다.
android {
...
dataBinding {
enabled true
}
}
그 후 데이터바인딩을 설정할 액티비티 뷰의 xml로 이동해서 소스를 열어봅니다.
최상단 루트를 layout 태그로 감싸줍니다.
기존의 xml 소스를 수정하는거라면 기존 최상단 레이아웃(예. ConstraintLayout 등)을 "layout" 바로 아래로 내리시면 됩니다.
그 후 이벤트를 만들때 참조할 데이터바인딩 변수명이 필요하니 data, vairable 태그를 추가하고 name에는 변수명을, type에는 데이터 바인딩을 통한 이벤트를 세팅할 (내 패키지명 + 액티비티 명 또는 프래그먼트 명)을 적어주면 됩니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/hello_text_view"
android:text="Hello!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<Button
android:id="@+id/btn_change"
android:text="Text Change!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/hello_text_view"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="main"
type="com.joel.jojo.MainActivity"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/hello_text_view"
android:text="Hello!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<Button
android:id="@+id/btn_change"
android:text="Text Change!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/hello_text_view"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class MainActivity : AppCompatActivity() {
// xml 파일명이 카멜케이스로 클래스가 자동생성 됩니다.
private lateinit var binding: ActivityMainBinding
var text = "Hello!"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// binding 세팅
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
// 현재 binding시킨 xml의 variable name
binding.main = this
// binding 버튼 클릭 이벤트
binding.btnChange.setOnClickListener {
text = "Hello Binding!"
// Data가 변동될 경우 binding된 View들에 Data 변화를 알려줌
binding.invalidateAll()
}
}
}
위 샘플용 코드는 간단하게 어떤 형식으로 사용을 하는지 알아보는 예제 입니다.
단순하게 하나의 TextView를 사용하여 Text를 바인딩 하기 때문에 이게 어디가 좋다는거지???라고 하실 수 있겠으나 xml에 DTO 또는 데이터 집합 클래스를 Bind 해서 해당 클래스가 변경되면 연결된 여러개의 View가 한번에 변경되기 때문에 엄청나게 편해집니다.
또 Databinding과 같이 BindingAdapter를 이용해 ImageView에 Glide, Fresco 같은 이미지 로딩 라이브러리를 이용해서 이미지를 출력을 쉽게 할 수 있고 Databinding과 찰떡궁합인 LiveData를 사용하면 Data가 실시간으로 변경될 때 View도 같이 변경되니 MVVM 패턴 구현 시 엄청나게 편리해집니다.
정리하면 다음과 같습니다.
1. Databinding을 사용하면 findViewById(), 버터나이프를 쓰지 않아도 xml에 만든 View들을 자동으로 만들어 준다.
2. Data가 바뀌면 알아서 바뀐 Data로 View를 변경하게 할수도 있다. (옵저블 사용시)
3. RecyclerView에서 각각의 item을 세팅 해주는 작업도 xml에서 다 써주면 알아서 척척 값이 들어간다. (요거 엄청 편리합니다.)
4. JakeWharton의 Butterknife가 Deprecated 되었고 구글에서 권장하므로 앞으로는 Databinding을 사용 해야한다.
본 포스팅은 내용이 지속적으로 업데이트 됩니다.
참고내용
https://developer.android.com/topic/libraries/data-binding
https://developer.android.com/jetpack?hl=ko
https://www.vogella.com/tutorials/AndroidDatabinding/article.html