Android/개발

[DataBinding] 안드로이드 DataBinding 기본 사용법 - 기본 예제

시계는 와치 2020. 1. 29. 20:54


안드로이드 DataBinding 기본 사용법 알아보기 - 기본 예제









 Android 생태계에서 이미 많이 사용되고 있는 DataBinding(데이터바인딩)은 간단하게 xml파일에 data를 연결(binding)해서 사용하는 것입니다. Activity에서 따로 View들을 정의해서 사용하지 않아도 되고 Data를 view에 연결시켜 두면 data가 변할 때 따로 세팅해주지 않아도 변경되게 할 수 있습니다.


 그럼 이제부터 DataBinding의 기본적인 사용법부터 알아보도록 하겠습니다.


 * 지금부터 진행될 예제는 Kotlin으로 작성될 예정이므로 Kotlin에 대해 간단히 알아보고 싶으시면 아래 글을 참고해주시기 바랍니다.

Kotlin vs. Java - 코틀린, 자바 차이점 비교





1. app 수준의 Build.gradle 파일 수정


android {

    ...

dataBinding {
enabled = true
}
}

- android block에 dataBinding을 추가해줍니다.


* 위와 같이 dataBinding을 추가해주면 아래 사진처럼 kotlin-kapt plugin을 설정하라고 나옵니다.



  사진처럼 안내 문구가 뜬다면 맨위쪽에 아래 코드를 추가합니다.

apply plugin: 'kotlin-kapt'






2. DataBinding을 사용 할 xml 파일 수정


activity_main.xml (1번 코드를 2번과 같이 수정합니다.)

1. 처음 생성할 때 만들어진 activity_main.xml

<?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/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

2. <layout> 태그로 전체를 감싸줍니다.

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

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

<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>





3. 사용하려는 Activity에서 binding Setting


MainActivity.kt

private lateinit var binding: ActivityMainBinding // xml 파일명이 CamelCase 표기로 바뀌고 Binding이 붙습니다.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
}





 위의 3단계를 진행하면 DataBinding 사용 준비가 완료됩니다. 사용 준비가 됐으니 이제 기본적인 사용방법을 알아보도록 하겠습니다. 첫번째로 xml 파일에서 <data>를 정의해주고 두번째로 Activity에서 data를 연결해줍니다. 마지막으로 Button도 하나 만들어 Button을 Click 했을 때 연결한 data가 변하도록 해보겠습니다.





1. xml 파일에서 data 정의


activity_main.xml

<data>

<variable
name="activity"
type="com.imaec.databindingex.MainActivity" />
</data>

<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{activity.text}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_change"
app:layout_constraintVertical_chainStyle="packed"/>
<Button
android:id="@+id/btn_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Text"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view"
app:layout_constraintBottom_toBottomOf="parent"/>

- <layout>과 <ConstraintLayout> 사이에 정의해줍니다.

- 위에 name은 변수/객체와 같이 사용하고 type은 Class 또는 자료형을 넣을 수 있습니다.

- Java나 Kotlin에서 객체를 사용하듯이 TextView의 text에 @{} 안에 data를 넣어줍니다.

- TextView에 들어간 text를 변경해 줄 Button을 만들어줍니다.






2. Activty 파일 수정


MainActivity.kt

var text = "TEST"
binding.activity = this
binding.btnChange.setOnClickListener {
text = "TEST22"
binding.invalidateAll()
}

- bindinb.activity : xml에서 정의한 data의 name

- binding.invalidateAll() : data가 변한 후 연결된 view들에 변화르 알려주는 함수





Example Full Source


build.gradle(app)

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
compileSdkVersion 28
defaultConfig {
applicationId "com.imaec.databindingex"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

dataBinding {
enabled = true
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.2.0-alpha04'
}


activity_main.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"
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="activity"
type="com.imaec.databindingex.MainActivity" />
</data>

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

<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{activity.text}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_change"
app:layout_constraintVertical_chainStyle="packed"/>

<Button
android:id="@+id/btn_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Text"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view"
app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>


MainActivity.kt

package com.imaec.databindingex

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.imaec.databindingex.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding

var text = "TEST"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.activity = this
binding.btnChange.setOnClickListener {
text = "TEST22"
binding.invalidateAll()
}
}
}






 이렇게 소스를 짜게되면 처음 앱이 실행되었을 때 TextView에 TEST가 표시되게 되고 Button을 Click하게 되면 TextView에 TEST22가 표시되게 됩니다. 위 예제는 단순히 하나의 TextView를 사용하기 때문에 장점을 잘 못느낄 수 있지만 xml에 DTO 클래스를 연결해서 DTO 클래스가 변경되면 연결된 여러개의 view가 한번에 변경되거나 BindingAdapter를 이용해 ImageView에 Glide로 이미지 표시하기 같은 것들을 할 수 있고 LiveData를 사용하면 data가 변경될 때 view도 같이 변경되는 좋은 경험을 하실 수 있습니다.

 나중에는 조금 더 난이도를 높여서 BindingAdapter 사용과 LiveData 사용 예제를 작성해보겠습니다.

 

 궁금하신점은 댓글로 남겨주시면 답변드리겠습니다^^


DataBinding, LiveData 함께 사용하는 방법

안드로이드 DataBinding과 LiveData 같이 사용하기


BindingAdapter 사용법

안드로이드 DataBinding에 BindingAdapter 사용법