[Android] DataBinding 사용 및 xml 스니펫 만들기
DataBinding 이란?
레이아웃 파일(xml)에 데이터를 결합(binding)해주는 Android JetPack 라이브러리 중 하나이다. Activity에서 findViewById()를 통해서 View를 가져올 필요가 없고, 연결된 데이터가 변할 때 쉽게 View에 변경된 데이터를 반영할 수 있는 장점이 있다.
1.gradle 파일 수정
app수준 gradle 파일에 android 스코프의 buildFeatures 에 dataBinding 을 추가한다.
(필자는 viewBinding을 사용하였다)
android {
...
buildFeatures{
viewBinding = true
dataBinding = true
}
....
}
2.DataBinding을 사용할 xml 파일 수정
레이아웃 수정
[item_excerise.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="itemExcerise" type="com.example.diffutillsample.entity.Excerise" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginHorizontal="20dp" android:layout_marginVertical="10dp"> <ImageView android:id="@+id/iv_excerise" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/squart_icon" android:padding="20dp" android:src="@drawable/icon_squart" android:background="@drawable/back_rect_round_10dp_gray" app:tint="@color/white" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginHorizontal="20dp" android:layout_marginTop="10dp" app:layout_constraintStart_toEndOf="@+id/iv_excerise" app:layout_constraintEnd_toStartOf="@+id/cb_excerise_done" app:layout_constraintTop_toTopOf="parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{itemExcerise.name}" android:textStyle="bold" android:textSize="20sp" android:layout_marginBottom="10dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{itemExcerise.formattedText}"/> </LinearLayout> <CheckBox android:id="@+id/cb_excerise_done" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginEnd="10dp" android:checked="false" android:button="@null" android:background="@drawable/sel_checkbox" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
root 태그로 <layout> </layout> 태그를 추가한다.
xml에 사용할 data 태그 안에 <variable/> 안에 선언한다.
사용하려는 Activity에서 binding 설정
1. binding 설정 하여 뷰를 구성
inner class ExceriseViewHolder(private val binding: ItemExceriseBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(excerise: Excerise, exceriseCheckStatus: ExceriseCheckStatus) {
// 전체 rootView를 클릭했을때 동작
// todo: 1.이미지뷰 백그라운드 및 tint 변경, 2.체크박스 변경
binding.apply {
itemExcerise = excerise
cbExceriseDone.isChecked = exceriseCheckStatus.isChecked
cbExceriseDone.setOnClickListener {
exceriseCheckStatus.isChecked = cbExceriseDone.isChecked
}
// 체크박스의 상태에 따라서 item 색 변경
cbExceriseDone.setOnCheckedChangeListener { _, isChecked ->
clickCheckBox(isChecked)
}
root.setOnClickListener {
val newCheckedState = !cbExceriseDone.isChecked
cbExceriseDone.isChecked = newCheckedState
exceriseCheckStatus.isChecked = cbExceriseDone.isChecked
}
}
}
private fun ItemExceriseBinding.clickCheckBox(isChecked: Boolean) {
if (isChecked) {
Log.d("isChecked", isChecked.toString())
ivExcerise.apply {
setColorFilter(
ContextCompat.getColor(
root.context,
R.color.light_green
)
)
setBackgroundResource(R.drawable.back_rect_round_10dp_green)
}
} else {
Log.d("isUnChecked", isChecked.toString())
ivExcerise.apply {
setColorFilter(
ContextCompat.getColor(
root.context,
R.color.white
)
)
setBackgroundResource(R.drawable.back_rect_round_10dp_gray)
}
}
}
}
2.데이터 초기화
itemExcerise(xml의 variable에 설정한 name) = excerise (넣을 데이터)
위 코드를 통하여 XML view 에 데이터를 초기화 한다.
+ xml 템플릿화 하기
데이터 바인딩을 적용하는 레이아웃을 자주 적용하면 아래 탬플릿 코드를 만들어 사용해 보자

1. layoutResource 코드 탬플릿 설정 변경
Editor -> Fire and Code Templates -> layoutResourceFile.xml 선택
4번 빨간색 박스 안에 레이아웃 화면 생성시 자동으로 들어가게할 탬플릿 소스 입력
Ex. 템플릿 코드
<?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="viewModel" type="{PACKAGE_NAME}.viewmodel.YourViewModel" /> </data> <${ROOT_TAG} android:layout_width="${LAYOUT_WIDTH}" android:layout_height="${LAYOUT_HEIGHT}"> </${ROOT_TAG}> </layout>
Scheme이 Project 로 설정되어 있으면 해당 프로젝트에만 적용됨
Scheme이 Default 로 설정되어 있을 시 새로 생성된 프로젝트에도 위 템플릿 사용 가능
2. 탬플릿 코드 사용
기본적으로 레이아웃 생성하는 것처럼 레이아웃 생성하면 위 탬플릿 대로 레이아웃이 생성되는 것을 확인할 수 있다
dataBinding 변수 부분인 variable 태그는 데이터 클래스에 맞게 내용 수정을 해주어야 한다.
<?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="viewModel"
type="{PACKAGE_NAME}.viewmodel.YourViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
참고
