Data Binding Guide-3

SeungyongYun
6 min readApr 25, 2016

--

이 문서는 구글의 Data Binding Guide의 내용을 번역후, 일부 수정하여 작성되었습니다.

이번에는 지난 시간에 이어 Data Binding에 사용되는 Data Object내 변수의 값이 변경 될 경우 자동으로 UI에 반영되는 기법에 대해서 알아보겠습니다.

Data Object

Data Binding의 꽃은 data의 변경이 UI에 반영된다는 점입니다. 총 3가지의 기법(Observable objects, Observable fields, observable collection)이 있는데 하나씩 알아보도록 하겠습니다.

Observable Objects

Observable 인터페이스를 implements 함으로써 멤버 변수에 대한 리스너를 지정해줄 수 있는데, Observable 인터페이스 자체에서는 리스너를 추가하거나 삭제하는 메카니즘만 가지고 있기 때문에, 실제 notifying하는 것은 전적으로 개발자에게 달려있습니다. 이 부분을 보다 쉽게 구현하기 위해서 BaseObservable을 상속받아 구현하는 형태가 주를 이루게 됩니다. 결과적으로 BaseObservable을 상속 받고, getter에는 @Bindable 어노테이션을 달고, setter에서 notify를 해주면 값이 변경될 때 마다 UI에 반영이 됩니다.

private static class User extends BaseObservable {
private String firstName;
private String lastName;
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getLastName() {
return this.lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
}

ObservableFields

Observable을 상속 받는 클래스를 만드는 것은 약간의 작업을 필요로 합니다. 만약 적은 양의 Properties만 Observable하게 만들고 싶거나, 기존의 클래스를 만드는 방법보다 조금 더 편한 방법을 찾는다면, ObservableField나 이것을 상속받은 ObservableBoolean, ObservableInt, ObservableLong, ObservableFloat, ObservableParcelable 등을 사용하길 권장합니다.

ObservableFields는 그 자체가 하나의 필드를 가지고 있는 Observable을 포함하고 있습니다. 만약에 사용하려면 관련된 필드는 public final 로 지정해줘야합니다.

private static class User {
public final ObservableField<String> firstName =
new ObservableField<>();
public final ObservableField<String> lastName =
new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}

변수에 접근하거나, 값을 설정해주기 위해서는 set, get 메서드를 사용하면 됩니다.

user.firstName.set("Google");
int age = user.age.get();

Observable Collections

어떤 앱들은 동적인 구조를 가진 데이터를 필요로할 때가 있는데, 이 경우, Observable collections는 key를 사용한 접근이 가능하게 하므로 활용하기 좋습니다.

ObservableArrayMap 은 키가 참조타입(e.g. String)일 경우에 유용합니다.

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);

layout 파일에서 map는 String key를 통해 접근할 수 있습니다.

<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap&lt;String, Object>"/>
</data>

<TextView
android:text="@{user[`lastName`]}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="@{String.valueOf(1 + (Integer)user[`age`])}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

ObservableArrayList 는 키가 int 일 경우에 유용합니다.

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);

이 경우, 바로 숫자 0, 1, 2를 사용하는 것 보다 상수로 지정해두어서 조금 더 가독성을 높이는 방식을 추천합니다.

<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList&lt;Object>"/>
</data>

<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

--

--