web-dev-qa-db-ja.com

ViewModelからLiveDataを観察する

データフェッチ(具体的にはFirebase)を処理する別のクラスがあり、通常はそこからLiveDataオブジェクトを返し、非同期に更新します。返されたデータをViewModelに保存したいのですが、問題は、その値を取得するために、データ取得クラスから返されたLiveDataオブジェクトを観察する必要があることです。 observeメソッドでは、最初のパラメーターとしてLifecycleOwnerオブジェクトが必要でしたが、ViewModel内には明らかにないので、ViewModel内のActivity/Fragmentへの参照を保持する必要はありません。私は何をすべきか?

51
Vuk Bibic

Google開発者JoseAlcérrecaによる このブログ投稿 では、この場合は変換を使用することをお勧めします(「リポジトリのLiveData」段落を参照)。

22
guglhupf

ViewModel ドキュメンテーション

ただし、ViewModelオブジェクトは、LiveDataオブジェクトなどのライフサイクル対応のオブザーバブルへの変更を決して監視してはなりません。

もう1つの方法は、LiveDataではなくRxJavaをデータに実装することです。これにより、ライフサイクルを認識できるという利点がなくなります。

todo-mvvm-live-kotlin のGoogleサンプルでは、​​ViewModelでLiveDataなしのコールバックを使用します。

ライフサイクルウェアであるという考え方全体に準拠したい場合は、アクティビティ/フラグメントの監視コードを移動する必要があると思います。それ以外の場合、ViewModelでコールバックまたはRxJavaを使用できます。

もう1つの妥協点は、MediatorLiveData(または変換)を実装し、ViewModelで観察(ここにロジックを配置)することです。 MediatorLiveDataオブザーバーは、Activity/Fragmentで監視されない限り、トリガーされません(変換と同じ)。ここで行うことは、アクティビティ/フラグメントに空白の監視を配置することです。実際の作業は、実際にはViewModelで行われます。

// ViewModel
fun start(id : Long) : LiveData<User>? {
    val liveData = MediatorLiveData<User>()
    liveData.addSource(dataSource.getById(id), Observer {
        if (it != null) {
            // put your logic here
        }
    })
}

// Activity/Fragment
viewModel.start(id)?.observe(this, Observer {
    // blank observe here
})

PS: ViewModels and LiveData:Patterns + AntiPatterns を読んで、その変換を提案しました。 LiveDataが観察されない限り、動作しないと思います(おそらく、Activity/Fragmentで行う必要があります)。

17
Desmond Lua

ライフサイクル所有者インターフェースを必要としないobserveForeverを使用でき、ビューモデルから結果を観察できると思います

1
siddharth