Android Data Binding 완벽 가이드
Android Data Binding 완벽 가이드
Android Data Binding은 UI 컴포넌트를 데이터 소스와 선언적으로 바인딩할 수 있게 해주는 라이브러리입니다. 이를 통해 boilerplate 코드를 줄이고 MVVM 패턴을 쉽게 구현할 수 있습니다.
기본 설정
Gradle 설정
android {
...
dataBinding {
enabled = true
}
}
레이아웃 파일 구조
Data Binding을 사용하려면 레이아웃 파일을 <layout> 태그로 감싸야 합니다.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.example.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
</LinearLayout>
</layout>
XML에서의 표현식 사용
기본 표현식
<!-- 문자열 연결 -->
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:text="@{user.lastName ?? user.firstName}"
Null 처리
<!-- Null 병합 연산자 -->
android:text="@{user.displayName ?? user.lastName}"
<!-- 조건부 표시 -->
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"
리소스 참조
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
android:text="@{@string/nameFormat(firstName, lastName)}"
android:text="@{@plurals/banana(bananaCount)}"
Import 사용
<data>
<import type="android.view.View"/>
<import type="com.example.MyStringUtils"/>
</data>
Listener Binding
Method Reference
<Button
android:onClick="@{handlers::onClickFriend}" />
Lambda Expression
<Button
android:onClick="@{() -> presenter.onSaveClick(task)}" />
<!-- 파라미터 전달 -->
<Button
android:onClick="@{(view) -> presenter.onButtonClick(view, user)}" />
Observable 데이터
ObservableField 사용
class User {
val firstName = ObservableField<String>()
val lastName = ObservableField<String>()
val age = ObservableInt()
}
LiveData와 함께 사용
class UserViewModel : ViewModel() {
val userName: LiveData<String> = MutableLiveData()
}
<data>
<variable
name="viewModel"
type="com.example.UserViewModel" />
</data>
<TextView
android:text="@{viewModel.userName}" />
Activity에서 LifecycleOwner 설정이 필요합니다:
binding.lifecycleOwner = this
BindingAdapter
커스텀 속성을 만들어 더 강력한 바인딩을 구현할 수 있습니다.
기본 BindingAdapter
@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url: String?) {
url?.let {
Glide.with(view.context)
.load(it)
.into(view)
}
}
<ImageView
app:imageUrl="@{user.profileImageUrl}" />
복수 속성 BindingAdapter
@BindingAdapter("imageUrl", "placeholder")
fun loadImageWithPlaceholder(
view: ImageView,
url: String?,
placeholder: Drawable?
) {
Glide.with(view.context)
.load(url)
.placeholder(placeholder)
.into(view)
}
기존 속성 오버라이드
@BindingAdapter("android:text")
fun setText(view: TextView, text: String?) {
// 커스텀 로직 추가
view.text = text?.uppercase()
}
ViewStub과 Data Binding
ViewStub은 필요할 때만 inflate되는 경량 뷰입니다.
<ViewStub
android:id="@+id/stub"
android:inflatedId="@+id/subTree"
android:layout="@layout/mySubTree"
android:layout_width="120dp"
android:layout_height="40dp" />
binding.stub.setOnInflateListener { _, inflated ->
val stubBinding: MySubTreeBinding = DataBindingUtil.bind(inflated)!!
stubBinding.user = user
}
binding.stub.inflate()
View Binding과의 차이
View Binding은 Data Binding의 경량 버전으로, 표현식 바인딩 없이 뷰 참조만 제공합니다.
View Binding 설정
android {
buildFeatures {
viewBinding = true
}
}
사용 예시
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello"
}
}
Include 레이아웃에 변수 전달
<!-- included_layout.xml -->
<layout>
<data>
<variable name="title" type="String"/>
</data>
<TextView
android:text="@{title}"/>
</layout>
<!-- main_layout.xml -->
<include
layout="@layout/included_layout"
app:title="@{@string/app_title}"/>
자주 발생하는 이슈와 해결책
빌드 에러
@BindingAdapter와@JvmStatic을 함께 사용할 때는 companion object 안에 정의해야 합니다.- 표현식에서 사용하는 클래스는 반드시 import 해야 합니다.
성능 최적화
- 복잡한 표현식은 ViewModel에서 처리하고 결과만 바인딩합니다.
- ObservableField보다 LiveData 사용을 권장합니다.
결론
Data Binding은 Android 앱 개발에서 UI와 데이터 로직을 분리하는 강력한 도구입니다. MVVM 아키텍처와 함께 사용하면 유지보수성이 높은 코드를 작성할 수 있습니다. 초기 학습 곡선이 있지만, 익숙해지면 개발 생산성이 크게 향상됩니다.
Comments