관측 가능성은 객체가 데이터 변경을 다른 사용자에게 알릴 수 있는 기능을 의미합니다. 데이터 결합 라이브러리를 사용하면 객체, 필드 또는 컬렉션을 식별 가능하도록 만들 수 있습니다.
데이터 결합에 모든 객체를 사용할 수 있지만 객체를 수정해도 UI가 자동으로 업데이트되지는 않습니다. 데이터 결합을 사용하여 데이터 변경 시 리스너라고 하는 다른 객체에 알리는 기능을 데이터 객체에 부여할 수 있습니다. 식별 가능한 클래스에는 세 가지 유형, 즉 필드, 컬렉션, 객체가 있습니다.
이러한 관찰 가능한 데이터 객체 중 하나가 UI에 결합되고 데이터 객체의 속성이 변경되면 UI가 자동으로 업데이트됩니다.
식별 가능한 필드
클래스에 속성 몇 개만 있는 경우 Observable
인터페이스를 구현하는 클래스를 만들지 않아도 됩니다. 이 경우 일반 Observable
클래스와 다음과 같은 프리미티브 관련 클래스를 사용하여 필드를 식별 가능하게 만들 수 있습니다.
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
식별 가능한 필드는 단일 필드가 있는 독립적인 식별 가능한 객체입니다. 프리미티브 버전은 액세스 작업 중에 박싱 및 언박싱을 방지합니다. 이 메커니즘을 사용하려면 다음 예와 같이 자바 프로그래밍 언어로 public final
속성을 만들거나 Kotlin으로 읽기 전용 속성을 만듭니다.
Kotlin
class User { val firstName = ObservableField<String>() val lastName = ObservableField<String>() val age = ObservableInt() }
Java
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()
접근자 메서드를 사용하거나 Kotlin 속성 문법을 사용합니다.
Kotlin
user.firstName = "Google" val age = user.age
Java
user.firstName.set("Google"); int age = user.age.get();
식별 가능한 컬렉션
일부 앱은 동적 구조를 사용하여 데이터를 보유합니다. 관찰 가능한 컬렉션을 사용하면 키를 사용하여 이러한 구조에 액세스할 수 있습니다. ObservableArrayMap
클래스는 다음 예와 같이 키가 String
과 같은 참조 유형일 때 유용합니다.
Kotlin
ObservableArrayMap<String, Any>().apply { put("firstName", "Google") put("lastName", "Inc.") put("age", 17) }
Java
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
다음 예와 같이 레이아웃에서 문자열 키를 사용하여 지도를 찾을 수 있습니다.
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<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
클래스는 다음과 같이 키가 정수일 때 유용합니다.
Kotlin
ObservableArrayList<Any>().apply { add("Google") add("Inc.") add(17) }
Java
ObservableArrayList<Object> user = new ObservableArrayList<>(); user.add("Google"); user.add("Inc."); user.add(17);
다음 예와 같이 레이아웃에서 색인을 통해 목록에 액세스할 수 있습니다.
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<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"/>
식별 가능한 객체
Observable
인터페이스를 구현하는 클래스를 사용하면 관찰 가능한 객체의 속성 변경 알림을 받으려는 리스너를 등록할 수 있습니다.
Observable
인터페이스에는 리스너를 추가하고 삭제하는 메커니즘이 있지만 알림이 전송되는 시점은 개발자가 결정합니다. 더 쉽게 개발할 수 있도록 데이터 결합 라이브러리는 리스너 등록 메커니즘을 구현하는 BaseObservable
클래스를 제공합니다. BaseObservable
를 구현하는 데이터 클래스는 속성이 변경될 때 알리는 역할을 합니다. 이렇게 하려면 다음 예와 같이 getter에 Bindable
주석을 할당하고 setter에서 notifyPropertyChanged()
메서드를 호출합니다.
Kotlin
class User : BaseObservable() { @get:Bindable var firstName: String = "" set(value) { field = value notifyPropertyChanged(BR.firstName) } @get:Bindable var lastName: String = "" set(value) { field = value notifyPropertyChanged(BR.lastName) } }
Java
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); } }
데이터 결합은 모듈 패키지에 BR
라는 클래스를 생성합니다. 이 클래스에는 데이터 결합에 사용되는 리소스의 ID가 포함됩니다. Bindable
주석은 컴파일 중에 BR
클래스 파일에 항목을 생성합니다. 데이터 클래스의 기본 클래스를 변경할 수 없는 경우 PropertyChangeRegistry
객체를 사용하여 Observable
인터페이스를 구현하여 리스너에 효율적으로 등록하고 리스너에 알릴 수 있습니다.
수명 주기 인식 객체
앱의 레이아웃은 데이터 변경사항을 UI에 자동으로 알리는 데이터 결합 소스에 결합할 수도 있습니다. 이렇게 하면 결합이 수명 주기를 인식하며 UI가 화면에 표시될 때만 트리거됩니다.
데이터 결합은 StateFlow
및 LiveData
를 지원합니다. 데이터 결합에서 LiveData
를 사용하는 방법에 관한 자세한 내용은 LiveData를 사용하여 UI에 데이터 변경사항 알림을 참고하세요.
StateFlow 사용
앱에서 Kotlin을 코루틴과 함께 사용하는 경우 StateFlow
객체를 데이터 결합 소스로 사용할 수 있습니다. 결합 클래스와 함께 StateFlow
객체를 사용하려면 수명 주기 소유자를 지정하여 StateFlow
객체의 범위를 정의하세요. 다음 예에서는 결합 클래스가 인스턴스화된 후 활동을 수명 주기 소유자로 지정합니다.
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Inflate view and obtain an instance of the binding class.
val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)
// Specify the current activity as the lifecycle owner.
binding.lifecycleOwner = this
}
}
아키텍처 구성요소에 레이아웃 뷰 결합에 설명된 대로 데이터 결합은 ViewModel
객체와 원활하게 작동합니다. 다음과 같이 StateFlow
와 ViewModel
를 함께 사용할 수 있습니다.
class ScheduleViewModel : ViewModel() {
private val _username = MutableStateFlow<String>("")
val username: StateFlow<String> = _username
init {
viewModelScope.launch {
_username.value = Repository.loadUserName()
}
}
}
다음 예와 같이 레이아웃에서 결합 표현식을 사용하여 상응하는 뷰에 ViewModel
객체의 속성과 메서드를 할당합니다.
<TextView
android:id="@+id/name"
android:text="@{viewmodel.username}" />
사용자의 이름 값이 변경될 때마다 UI가 자동으로 업데이트됩니다.
StateFlow 지원 사용 중지
Kotlin과 AndroidX를 사용하는 앱의 경우 StateFlow
지원이 데이터 결합에 자동으로 포함됩니다. 즉, 종속 항목을 아직 사용할 수 없는 경우 코루틴 종속 항목이 앱에 자동으로 포함됩니다.
build.gradle
파일에 다음을 추가하여 이 기능을 선택 해제할 수 있습니다.
Groovy
android { ... dataBinding { addKtx = false } }
Kotlin
android { ... dataBinding { addKtx = false } }
또는 gradle.properties
파일에 다음 줄을 추가하여 프로젝트에서 StateFlow
를 전역적으로 사용 중지할 수 있습니다.
Groovy
android.defaults.databinding.addKtx = false
Kotlin
android.defaults.databinding.addKtx = false
추가 리소스
데이터 결합에 관한 자세한 내용은 다음을 참고하세요.
샘플
Codelab
블로그 게시물
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- ViewModel의 저장된 상태 모듈
- 아키텍처 구성요소에 레이아웃 뷰 결합
- Paging 라이브러리 개요