Skip to content
Go back

Data Binding

Data Binding 에 대한 정리

참고사이트

Data Binding

간단히 말해, 기존 아래와 같은 코드를

findViewById<TextView>(R.id.sample_text).apply {
    text = viewModel.userName
}

아래처럼 쓸 수 있는것

<TextView
        android:text="@{viewmodel.userName}" />

What to do to use?

Gradle 에 아래와 같이 추가 (View binding 과 같다)

android {
        ...
        dataBinding {
            enabled = true
        }
    }

Data Binding

View binding 과 마찬가지로, layout name + Binding 으로 데이터 바인딩 클래스 생성됨.
e.g) activity_main.xml -> ActivityMainBinding

Layout binding & expression

<?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:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
           <TextView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="@{user.firstName}"/>
           <TextView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="@{user.lastName}"/>
       </LinearLayout>
    </layout>

User 라는 클래스가 있다고 가정, TextView 에서 User 의 firstName, lastName 을 갖다쓰는걸 볼 수 있다.
@{} 구문을 사용.

그렇다면 데이터 결합은? 아래처럼

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

    val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main) // View binding 에서처럼 inflate() 를 이용할 수도 있다.

    binding.user = User("Test", "User")
}

binding.user 로 Test user 가 들어가겠지

Fragment, listView, RecytclerView 같은 어댑터 내에서 Binding 하는 경우는 DataBindingUtil.Inflate() 사용할 수 있음

val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
    // or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

표현식

android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'

위처럼 각 연산자 사용 가능.

뷰 참조

아래처럼 ID로 다른 뷰 참조 가능

<EditText
        android:id="@+id/example_text"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"/>
    <TextView
        android:id="@+id/example_output"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{exampleText.text}"/>

그 외도 다양한 참조 방법 가능.

Method 참조

핸들러를 정의하고, 이벤트에 핸들러를 결합하여 사용할 수 있음 아래처럼 사용하는 경우의 장점은 컴파일 타임에 처리가 된다. 따라서 메서드가 없거나 서명이 올바르지 않으면 컴파일 에러 발생할 수 있음.


    class MyHandlers {
        fun onClickFriend(view: View) { ... }
    }
<?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable name="handlers" type="com.example.MyHandlers"/>
           <variable name="user" type="com.example.User"/>
       </data>
       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
           <TextView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="@{user.firstName}"
               android:onClick="@{handlers::onClickFriend}"/>
       </LinearLayout>
    </layout>

Listener 결합

이벤트가 발생할때 실행되는 결합 표현식. 메서드 참조와 비슷하지만 임의의 데이터 표현식을 실행할 수 있음.

class Presenter {
        fun onSaveClick(task: Task){}
    }
<?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable name="task" type="com.android.example.Task" />
            <variable name="presenter" type="com.android.example.Presenter" />
        </data>
        <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="@{() -> presenter.onSaveClick(task)}" />
        </LinearLayout>
    </layout>

Import (가져오기)

Layout 내에서 클래스를 쉽게 참조할 수 있음.

<data>
    <import type="android.view.View"/>
</data>
<TextView
       android:text="@{user.lastName}"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>

클래스 이름이 충도랗면 이름을 별칭으로 바꿀수 있음.

<import type="android.view.View"/>
    <import type="com.example.real.estate.View"
            alias="Vista"/>

다른 클래스 가져오기

<data>
        <import type="com.example.User"/>
        <import type="java.util.List"/>
        <variable name="user" type="User"/>
        <variable name="userList" type="List&lt;User>"/>
    </data>
    

아래처럼 Type convert도 가능

<TextView
       android:text="@{((User)(user.connection)).lastName}"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

static field, method 도 사용 가능

<data>
        <import type="com.example.MyStringUtils"/>
        <variable name="user" type="com.example.User"/>
    </data>

    <TextView
       android:text="@{MyStringUtils.capitalize(user.lastName)}"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

변수도 사용 가능

<data>
        <import type="android.graphics.drawable.Drawable"/>
        <variable name="user" type="com.example.User"/>
        <variable name="image" type="Drawable"/>
        <variable name="note" type="String"/>
    </data>

Share this post on:

Previous Post
Data Binding \uC608\uC81C
Next Post
View Binding