[Android]/학습

[Android/Kotlin] 안드로이드 학습 2.4 - Data Binding

Cocoa's Story 2022. 11. 1. 17:02

이번 시간에 알아볼 것은 findViewById 보다 효율적인 Data Binding을 이용한 뷰의 참조이다.

 

 

Android Kotlin Fundamentals 02.4: Data binding basics  |  Android Developers

Learn how to use data binding to simplify code for accessing views in your Android app.

developer.android.com

 

 

findViewById

뷰의 계층 구조가 복잡하다면 findViewById로 뷰를 계속 참조하게 될 시 비용이 많이 들고, 앱이 느려진다. Android가 루트에서 시작하여 원하는 보기를 찾을 때까지 보기 계층 구조를 탐색하기 때문이다.

 앞선 실습에서는 뷰에서 데이터를 설정하려면 문자열 리소스를 사용하고 액티비티에서 데이터를 설정했다. 뷰가 데이터에 대해 알고 있다면 앞선 문제를 해결할 수 있고 더 효율적이다. 다행히 안드로이드에서 이를 가능하게 할 방법이 있다.

 

 

Data Binding

앞선 문제에 대한 해결책은 각각의 뷰에 대해 참조하는 객체를 만드는 방법이다. 'binding' 객체라 불리는 이 객체는 앱 전체에서 사용될 수 있는데, 그 기술은 'data binding'이라 부른다. 바인딩 객체가 앱에서 한번 생성되면, 이 바인딩 객체를 이용해 뷰와 다른 데이터에 손쉽게 접근할 수 있다. 얘만 있으면 더이상 매번 뷰 계층 구조를 탐색하거나 데이터를 검색할 필요가 없어지는 것이다!

데이터 바인딩을 사용했을 때의 이점은 아래와 같다.

  • findViewById()를 사용하는 코드보다 1. 짧고, 2. 읽기 쉽고, 3. 유지 관리하기 쉽다.
  • 데이터와 뷰가 명확하게 분리된다. 
  • Android 시스템이 각각의 뷰를 가져오기 위해 뷰 계층 구조를 오직 한 번만 탐색함. 이 과정은 사용자와 앱이 상호작용하는 런타임이 아니라 앱 시작중에 발생함 
  • 뷰 엑세스에 대한 형식 안정성(type safety)를 얻는다. 형식 안정성이란 컴파일러가 컴파일하는 동안 형식의 유효성을 검사하고, 변수에 잘못된 형식을 할당하고자 하면 오류가 발생함을 의미한다.

 

데이터 바인딩 과정

1. 데이터 바인딩 활성화

데이터 바인딩은 기본적으로 활성화되어있지 않으므로 Gradle 파일에서 데이터 바인딩을 활성화 해주어야 한다.

build.gradle (Module: app) 파일에서 

buildFeatures {
    dataBinding true
}

코드를 추가하고, sync now 버튼을 누른다.

 

 

2. 데이터 바인딩을 사용할 수 있도록 레이아웃 파일 수정

<LinearLayout>바깥을 <layout></layout>로 감싸준다.

<layout>
   <LinearLayout ... >
   ...
   </LinearLayout>
</layout>

layout에 대한 네임스페이스 선언은 가장 바깥에 있어야 함. LinearLayout 안에 있는 네임스페이스 선언을 잘라내 layout 안으로 넣어준다.

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

LinearLayout 태그 안에는 보기 속성만 있어야 함.

 

 

3. MainActivity에 바인딩 객체 생성

onCreate() 이전에 바인딩 객체 변수 생성

private lateinit var binding: ActivityMainBinding

이름은 레이아웃 파일의 이름에서 파생된다. (activity_main + Binding)

위 코드가 추가되고 나면 ActivityMainBinding이 import 될 것이다.

import com.example.aboutme.databinding.ActivityMainBinding

 

현재 setContentView() 함수의 내용을 다음을 고려해 변경하자.

  • 바인딩 객체 생성
  • DataBindingUtil 클래스 이용 -> activity_main 레이아웃을 MainActivity에 할당해줌
  • onCreate()에서 setContentView()를 호출하는 부분을 아래의 코드로 바꿔줌
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

 

 

4. 만들어준 바인딩 객체를 활용해 findViewById()로 한 모든 호출을 대체

준비가 모두 끝났으니 이제 진짜 findViewById()와 작별해보자. findViewById()로 호출한 모든 것들을 바인딩 객체에 있는 뷰의 참조로 대체해주겠다. 여기서 짚고 넘어갈 점! 바인딩 객체가 만들어질 때, 컴파일러는 레이아웃의 뷰 id로부터 바인딩 객체는 뷰의 이름을 카멜케이스로 바꿔 생성한다. 

ex) done_button -> doneButton, nickname_edit -> nicknameEdit.

findViewById<Button>(R.id.done_button)

위의 코드를

binding.doneButton

로 바꿔줄 수 있다.

 

마찬가지로 모든 코드를 바인딩 객체로 바꿔준 후 앱을 다시 빌드해 보자.

코드를 모두 바꿔 주었음에도 잘 돌아가는 것을 확인할 수 있다.

 

 

 

Use data binding to display data

1. Data Class 만들기

MyName 데이터 클래스를 만들어준다.

data class MyName(var name: String = "", var nickname: String = "")

 

 

2. 레이아웃에 data 추가

<layout>
	<data>
  
	</data>
	<LinearLayout>
    ...
	</LinearLayout>
</layout>

activity_main.xml <layout>과 <LinearLayout> 사이에 <data> 태그를 넣어준다.

<variable
       name="myName"
       type="com.example.android.aboutme.MyName" />

<data> 태그 안에 위의 <variable> 태그를 넣어준다.

 

이제부터 이름으로 스트링 리소스를 사용하는 대신, myName 변수를 참조할 수 있게 되었다.

android:text="@string/name" 코드를 아래로 바꿔준다.

android:text="@={myName.name}"

@={} : 중괄호 내에  참조되는 데이터를 가져옴

myName은 myName 데이터 클래스를 가리키고 클래스에서 name 속성을 가져오는 이전에 정의한 myName 변수를 참조한다.

 

 

3. 데이터 만들기

이제 레이아웃 파일에 데이터에 대한 참조가 생겼으니, 실제 집어넣을 데이터를 만들자.

MainActivity.kt onCreate() 이전에

private val myName: MyName = MyName("Cocoa")

onCreate() 안에

binding.myName = myName

 

 

4. nickname TextView에서 데이터 클래스 사용하기

android:text="@={myName.nickname}"

지정

MainActivity.kt에서

binding.nicknameText.text = binding.nicknameEdit.text

코드 대신

myName?.nickname = nicknameEdit.text.toString()

 

 

Learn more

Udacity course:

Android developer documentation: