web-dev-qa-db-ja.com

LiveDataを監視するViewmodel-どのように?

LifecycleおよびLiveDataが機能する前は、Viewmodelは自身の監視対象への変更を非常に簡単に監視できました。 Observable*の変更をサブスクライブし、それに対応するだけでした。次に、双方向バインディングを使用して、ユーザーの入力に即座に反応する場合があります。

Android Studio Canaryでは、Bindingが所有者のライフサイクルを認識している場合(ViewBindingに追加のsetLifecycleメソッドがあります)、LiveDataオブジェクトへのバインドが許可されるようになりました Android Studioカナリア情報

LiveDataオブジェクトをデータバインディング式の監視可能なフィールドとして使用できるようになりました。 ViewDataBindingクラスに、LiveDataオブジェクトの監視に使用する必要のある新しいsetLifecycleメソッドが含まれるようになりました。

ただし、 Viewmodelドキュメント は明確に述べています:

ViewModelオブジェクトには、LiveDataオブジェクトなどのLifecycleObserversを含めることができます。 ただし、ViewModelオブジェクトは、LiveDataオブジェクトなどのライフサイクル対応の監視対象への変更を監視してはなりません。

(私の強調)

では、ViewModelがLiveDataの変更にサブスクライブできない場合、LiveDataの変更にすぐに対応するにはどうすればよいでしょうか。

さらに、whyViewmodelが自身のLiveDataへの変更を監視できないのはなぜですか?

9
Spook

MediatorLiveDataを使用してこの問題を修正しました。以下の手順に従ってください。

  1. 変数を作成します(例:結果)。

    private final MediatorLiveData<Resource<RequestType>> result = new MediatorLiveData<>();
    
  2. addSourceメソッドを呼び出します。最初の引数はLiveDataで、2番目の引数はオブザーバーです。

    LiveData<Resource<EmptyResponse>> observable = service.createItems();
    result.addSource(observable, response -> {
        //Write code here 
    }
    

this SO answer も参照してください。基本的な要件はほぼ同じです。

3
Saurabh Khare

Transformations を使用して、LiveDataオブジェクトの1つが変更された場合にアクションを呼び出すことができます。

例えば。ユーザーがSpinnerで人を選択し、それに応じた人オブジェクトをロードしたいとします。

MutableLiveData<Integer> personId = new MutableLiveData<>();
LiveData<Person> person = Transformations.switchMap(personId, id -> getPerson(id));
2
woodii