Android - findViewById() 대신 데이터 바인딩을 사용해보자

안드로이드 앱을 개발할 때 일반적으로 사용하는 기능 중 하나가 바로 findViewById()입니다. 특정 TextView의 문자 값을 변경하거나 이벤트를 처리할 때 등등 화면의 요소를 findViewById()로 찾아 제어합니다.

val textView: TextView = findViewById(R.id.text_main)

이런 코드로 말이죠. 하나의 TextView 정도야 예제 코드처럼 쉽게 쓸 수 있지만 화면에서 관리해야 하는 요소가 늘어날수록 findViewById()는 부담스러울 정도로 늘어납니다.

 

 이러한 부분을 조금 더 간결한 코드로 손쉽게 해결할 수 있는 방법이 데이터 바인딩입니다. 데이터 바인딩은 데이터와 화면을 연결 짓는 기술로 안드로이드 앱뿐만 아니라 화면과 관련된 기술들(WinForm, WPF, Angularjs, React, Vue 등등)에서는 이전부터 사용되어왔고 계속 발전해나가는 기법 중에 하나입니다.

 

 안드로이드에서 제공하는 데이터 바인딩을 사용하면 findViewById()를 사용하지 않아도 화면의 요소를 제어할 수 있습니다. 데이터 바인딩은 findViewById() 사용하지 않는 방법이 아닙니다. 그저 데이터와 화면(UI)을 연결해서 사용하는 방법일 뿐입니다.

데이터 바인딩 설정하기

 데이터 바인딩을 사용하기 위해서는 먼저 빌드 설정(app/build.gradle)을 수정해야 합니다.

android {
    // ...
    dataBinding {
        enabled true
    }
}

 안드로이드에서 제공하는 데이터 바인딩을 사용하기 위해 build.gradle 파일을 수정했다면, Layout 파일을 수정할 차례입니다. <layout> 태그를 정의해서 모든 요소를 감싸주세요. <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_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

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

데이터 바인딩 사용하기

 자 이제 findViewById() 대신 데이터 바인딩을 사용해 화면 요소를 다루는 방법을 알아보겠습니다.  먼저 findViewById()를 사용해 TextView의 문구를 수정하는 코드입니다.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        val textView: TextView = findViewById(R.id.text_main)

        textView.text = "Hello New World!"
    }
}

 처음 안드로이드 앱을 만들면 바로 사용할 수 있는 간단한 예제입니다. 이 코드에 데이터 바인딩을 적용해보겠습니다.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)

        setContentView(binding.root)

        val textMain: TextView = binding.textMain
        textMain.text = "Hello New World!"
        
        // binding.textMain.text = "Hello New World!"
    }
}

 데이터 바인딩을 하기 위해서는 ActivityMainBinding을 사용해 Layout을 맵핑해야 합니다. Layout을 맵핑하면 binding(ActivityMainBinding)을 사용해 Layout이 가지고 있는 요소에 예제 코드와 같이 접근할 수 있습니다. findViewById()를 사용하지 않아도 Layout 요소를 제어할 수 있습니다.

데이터 바인딩 맛보기 - 단방향 바인딩

 findViewById()를 사용하지 않는 것만으로도 코드를 유지 보수하기가 한결 편해집니다. 하지만 데이터 바인딩이 가지는 이점은 여기에 있지 않습니다. 데이터 바인딩이 가지는 이점은 데이터와 화면을 연결함으로써 데이터가 변경되면 화면이 업데이트되고 화면의 값이 수정되면 데이터가 업데이트된다는 점입니다.

 

 그럼 간단하게 데이터를 화면에 연결하는 방식(단방향 바인딩)에 대해 알아보겠습니다.

data class Person(val name: String, val age: Int)

 화면에 보여 줄 데이터 클래스를 정의합니다. 이 코드는 예시이니 필요하다면 예제 코드처럼 data class를 정의하지 않아도 됩니다.

<?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="person" type="com.example.myapplication.Person"/>
    </data>
    // ...
</layout>

 data class를 추가했다면 데이터(값)를 레이아웃의 변수로 취급할 수 있게 Layout 파일에 추가해주세요.

<TextView
    android:id="@+id/text_main"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text='@{"사용자의 이름은 " + person.name + ", 직업은 " + person.job + "입니다"}'
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

 <data>에 정의된 변수는 해당 레이아웃 내에서 사용할 수 있는 값이 됩니다. 데이터 바인딩 표현식( @{ } )을 사용해 person의 값을 사용하게 수정해주세요. 데이터 클래스를 변수로 선언하고 어떻게 사용할지 Layout 파일에 정의했으니 이제 값을 사용할 수 있게 할당해보겠습니다.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)

        setContentView(binding.root)

        val person = Person("YD", "Developer")

        binding.person = person
    }
}

 그럼 이제 결과를 확인해보겠습니다.

안드로이드 앱 실행 결과 (단방향 바인딩)

 글에서 사용한 코드는 첨부파일로 제공되니 필요하신 분은 다운로드하여 사용해주세요. 첨부파일 외에도 Github로도 해당 코드는 제공합니다.

hello-android-demo-data-binding.zip
0.11MB

데이터 바인딩을 사용하는 이유

 특정 상황에 텍스트 값을 변경하는 요구 사항이 있다고 가정했을 때, findViewById()를 사용하면 텍스트를 넣어야 할 요소를 하나하나 가져와 값을 넣어야 합니다. 하지만 데이터 바인딩을 사용하면 그럴 필요 없이 의미 그대로 Layout에서 데이터를 바인딩해주면 됩니다.

반응형

댓글

Designed by JB FACTORY