: 이 포스트는 "안드로이드 개발 레벨업 교과서" 책을 요약한 내용이다. 구체적인 내용이 궁금하다면 이 책을 구매해서 읽어보면 좋겠다. 해당 포스트에서 활용할 예제 소스는 https://github.com/wikibook/advanced-android-book/tree/master/tech05/DataBindingSample 이다. 이 예제를 통해 MVVM 설계를 하는 데 중요한 데이터 바인딩에 대해서 알아볼 것이다. 아래 사진처럼 구현할 것이다. "좋아요" 버튼을 누르면 위에 있는 숫자가 늘어난다.




1. 데이터 바인딩을 이용하려면 build.gradle에 데이터 바인딩을 활성화 해야 한다. 

android {
	....
	dataBinding {
		enable=true
	}
	....
}


2. 레이아웃 파일에 바인딩할 클래스를 기술한다.

: 데이터 바인딩을 하려면 XML 파일의 루트를 layout 태그로 해야 한다. <data> 태그를 통해 바인딩할 클래스를 기술한다. 아래는 ~ sample.User 클래스를 바인딩하되 이름을 user로 하겠다는 뜻이다.

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.github.advanced_android.databindingsample.MainActivity"> <data> <!-- User 클래스에 바인딩한다 --> <variable name="user" type="com.github.advanced_android.databindingsample.User"/> </data> <LinearLayout ...... </LinearLayout> </layout>

아래와 같이 뷰와 데이터를 연결할 수 있다. android:onClick 부분은 User 클래스의 onClickLike 메서드와 연결된다.

<TextView
    android:text="@{user.name}"

    ...


<TextView
    android:text="@{String.valueOf(user.likes)}"
    
    ....

<ImageButton
    android:onClick="@{user::onClickLike}"
   
    ....

다음은 위 프로젝트 예제의 전체 xml 소스이다.

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.github.advanced_android.databindingsample.MainActivity">

    <data>
        <!-- User 클래스에 바인딩한다 -->
        <variable
            name="user"
            type="com.github.advanced_android.databindingsample.User"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        >

        <!-- 시간을 표시한다 -->
        <TextView
            android:id="@+id/text_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"/>

        <!-- 프로필 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="프로필"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="이름:"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="@{user.name}"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="나이:"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="@{String.valueOf(user.age)}"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="LIKE:"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="@{String.valueOf(user.likes)}"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>


        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{user::onClickLike}"
            android:src="@drawable/ic_thumb_up_black_36dp"
            />

    </LinearLayout>
</layout>


3. 바인딩하는 클래스를 구현한다.  

: XXX.set(YYY)를 사용하면 실제 UI도 바뀌게 된다. TextView.setText() 등을 호출할 필요가 없다. XXX.get()을 하면 해당 UI 값을 얻을 수 있다. 또한 onClickLike를 xml에서 지정해 리스너 또한 별도로 구현할 필요 없다. 

public class User {
    public ObservableField<String> name = new ObservableField<>();
    public ObservableInt  age = new ObservableInt();
    public ObservableInt likes = new ObservableInt();

    public User(String nameString, int ageInt) {
        name.set(nameString);
        age.set(ageInt);
        likes.set(0);
    }

    public void onClickLike(View view){
        likes.set(likes.get() + 1);
    }
}


4. 클래스 인스턴스와 레이아웃을 연결한다.  

: 아래 코드에서 binding.textTime.setText()의 의미은 binding과 연결된 xml 레이아웃에서 id 가 text_Time인 뷰에 setText(data)를 하라는 것이다.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Binding 오브젝트를 얻는다
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        // Binding 오브젝트에 User를 설정한다
        binding.setUser(new User("kim", 25));

        String date = (String) DateFormat.format("yyyy/MM/dd kk:mm:ss", Calendar.getInstance());
        binding.textTime.setText(date);
        //뷰에 id가 지정돼 있으면, Binding 오브젝트로부터 뷰에 대한 참조를 얻을 수 있다
    }


+ Recent posts