RxJava의 Observable과 LiveData와 ObservableField를 좋은 느낌으로 사용합시다.
위에서 LiveData는
라는 것을 썼습니다.
이번 기사에서는, 위에서 든 미묘한 3가지 점을 해소하기 위해서, RxJava와 LiveData와 DataBinding을 좋은 느낌으로 병용해 보고 싶습니다. 이번에도 코드는 Kotlin입니다.
RxJava with Android DataBinding
RxProperty를 사용합시다!
예 종료.
RxProperty에 대해 쓰는 몇번째, 자신.
저자 @k-kagurazaka @github 씨도 빚을지고, 사이코입니다, 사랑 해요 RxProperty , 더 를! !
RxProperty<T>
는 기본적으로는 Observable<T>
(라고 하는지 Subject<T>
)입니다만, .value
프로퍼티로 ObservableField<T>
로 변환할 수 있습니다.// MainViewModel.kt
class MainViewModel : ViewModel() {
// GitHub ユーザー名。EditText.text から双方向(TwoWay)バインドされる。
val user = RxProperty<String>()
init {
user.set("hogehoge")
}
}
activity_main.xml
<?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">
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.amay077.livedatasample.view.MainActivity"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="GitHub user name"
android:text="@={viewModel.user.value}"/> ←-- user.value とすることで ObservableField に!
</LinearLayout>
</layout>
이와 같이 레이아웃 XML에,
viewModel.user.value
라고 기술하면 데이터 바인딩 할 수 버립니다. 위의 예에서는 제대로 양방향 바인딩도 효과가 있습니다.RxJava with LiveData
이것은 「RxJava 의
Observable<T>
로부터 LiveData<T>
로 변환하는 확장 메소드」를 만들어 봅시다.// ObservableExtensions.kt
/**
* Observable<T> を LiveData<T> に変換
*/
fun <T> Observable<T>.toLiveData() : LiveData<T> {
return object : MutableLiveData<T>() {
var disposable : Disposable? = null;
// ライフサイクルがActiveになったときに購読開始
override fun onActive() {
super.onActive()
// Observable -> LiveData
disposable = this@toLiveData.subscribe({
this.postValue(it)
})
}
// ライフサイクルが非Activeになったら購読停止
override fun onInactive() {
disposable?.dispose();
super.onInactive()
}
}
}
라이프사이클이 비액티브(구체적으로는 onPause)가 되었을 때에 구독 정지해 주면 반드시 괜찮을 것.
다음과 같은 느낌으로 사용할 수 있습니다.
// MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
<いろいろ省略>
// RxProperty を LiveData に変換。
val liveDataUser = viewModel.user.toLiveData()
// LiveData を購読
liveDataUser.observe(lifecycleOwner, Observer {
editUserName.setTextKeepState(it)
})
}
}
보통은
RxProperty.value
그리고 DataBinding 하면 좋다고 생각합니다만, BindingAdapter 를 만드는 것이 번거롭거나 View측에서 조금 손질한 것을 하고 싶은 경우에는 .toLiveData()
로 LiveData 로 변환해, 안전 구독 관리를 즐길 수 있습니다.LiveData를 직접 사용하는 것이 더 좋은 경우
RxProperty -> LiveData 할 때의 주의점으로서, 값이 변경시 밖에 통지되지 않는다, 라고 하는 것이 있습니다.
어제 쓴 와 같이, LiveData 의 특성은, 동치 체크는 특별히 없고 값이 설정되면 (자)
onChanged
로 설정해도 처음만 통지됩니다.그 때문에, Model->ViewModel->View의 방향으로, 값을 다만 흘러 흘려, View측에서 수신해 무엇인가 하고 싶은 경우는, LiveData 를 그대로 사용하는 것이 좋을 것입니다. 이것은 EventBus(Messenger)적인 사용법입니다.
// MainViewModel.kt
class MainViewModel : ViewModel() {
// View 側から購読して Toast を表示するための LiveData。
// 変更通知が必要ない(=EventBus的に使う)なら、LiveData をそのまま使うのがいいんじゃなイカ。
private val _toast = MutableLiveData<String>()
val toast : LiveData<String> = _toast
fun showToast(view:View) {
toast.set("トーストだよ")
}
}
// MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
<いろいろ省略>
// Toast を表示するために、 toast:LiveData を購読する。
viewModel.toast.observe(this, Observer { message ->
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
})
}
}
위의 예는 토스트를 표시하기 위해
RxJava 風に言うと distinctUntilChanged なので
를 사용합니다.그 외에는 다이얼로그 박스의 표시나, 화면 천이의 요구 메세지를 View 측에 통지하기 위해서는 LiveData 를 그대로 사용하는 것이 좋다고 생각합니다 (라고 할까 거기를 Observable 로 할 필요를 느끼지 않는다).
완성 시스템
지난번 , 샘플로 GitHub의 리포지토리 목록을 검색하는 앱을 만들고 있었습니다.
그것을,
전부 사용해 써본 코드가 이쪽↓입니다.
스크린샷은 이런 거야.
AAC 시대에서도 Observable centric인 생각으로 좋지 않을까요.
그림에 정리하면 이런 느낌입니다.
RxProperty가 유행하지 않는 이유를 모르는 것입니다. 모두 사용해보십시오!
Reference
이 문제에 관하여(RxJava의 Observable과 LiveData와 ObservableField를 좋은 느낌으로 사용합시다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/amay077/items/58e589780ccea6fd5470텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)