web-dev-qa-db-ja.com

あるビューモデルから別のビューモデルにデータを渡すAndroid MVVM

デザイン関係の質問があります。

したがって、私はKotlin、MVVM、およびデータバインディングを使用してアプリケーションを構築するために、Googleによって Guide to App Architecture に従っています。 Googleが規定するJetpackコンポーネント(ナビゲーション、ライブデータなど)を使用しています。

問題は、開発中に何度もフラグメント間でデータを転送する必要があることです。以前は、フラグメントのインスタンスを作成して複雑なデータを追加してから、次のようにフラグメントに移動していました。

class Frag1: Fragment(){

    ...
    fun openFrag2(){
        val frg2 = frag2.newInstance(complexDataObj)
        childFragmentManager.addFragment(frg2,TAG)
    }
}

class Frag2: Fragment(){
    var cd: ComplexDataClass = null
    companion object{
    fun newInstance(complexData: ComplexDataClass): Fragment{
        val frag = ActivityFragment()
        frag.cd = complexData
        return frag
    }
    ....
}

navigation を使用すると、宛先間でデータを渡すことは this のようになるか、またはShared View Modelこれも同じドキュメントで言及されています。 >>

一般に、宛先間では最小限のデータのみを渡すことを強くお勧めします。たとえば、保存されているすべての状態の合計スペースはAndroidで制限されているため、オブジェクト自体を渡すのではなく、キーを渡してオブジェクトを取得する必要があります。大量のデータを渡す必要がある場合、フラグメント間でデータを共有するで説明されているようにViewModelの使用を検討してください。

これは機能します。

私が問題とするのは、アーキテクチャを使用する主な理由の1つが懸念の分離であるということです。そのため、クリーンで保守可能なコードを記述できます。 sharedviewmodelをこのように使用すると、目的が(私の理解によれば)無効になります。これは、ViewModelクラスが大きくなるためです。

ごく一般的なシナリオで問題を説明しようと思います。

データのリストを含むフラグメントがあります。リストの各項目はユーザーに対応しています。アイテムをタップすると、ユーザーの詳細画面に移動します。編集ボタンをタップすると、詳細を編集できる編集画面に移動します。

             View User Frag
             ____                 ____________
            |    |               |            |
 List Frag  |    |               |            |
 ______     |____|               |            |
|______| /
|______|/                        |            |
|______|\                        |            | Huge Shared ViewModel class
|______| \
            Edit User Frag       |            |
            _____
           |     |               |            |
           |     |
           |_____|               |____________|

したがって、この状況では、ユーザーデータをリストクラスからビューおよび編集フラグメントに送信する必要があるため、ViewModelはこれらの3つのフラグメント間で共有され、共有されたViewModelは3つのフラグメントすべてのビジネスロジックを持ちます。

したがって、これは私には適切ではないようです。ViewModelは複雑すぎて、多くの場合、次のように共有するように管理できないためです。

model = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.Java]
    } ?: throw Exception("Invalid Activity")

ビューモデルの同じインスタンスを提供します。

このsharedviewmodelに対する私の理解が間違っているかどうかを知る必要があります。間違っている場合は修正してください。私の理解が正しければ、そのような場合にビューモデルをより効率的に管理する方法を教えてください。

6
hushed_voice

ViewModelには複数のFragmentsを含めることができるため、3つの小さいロジックをすべて備えた巨大な共有ViewModelを保持する必要はありません。

実際の共通データのみを対象とする追加の共有ViewModelを作成し、3つの個別のフラグメント固有のViewModelsを個別に保持できます。

sharedModel = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.Java]
    } ?: throw Exception("Invalid Activity")
localViewModel = ViewModelProviders.of(this).get(LocalViewModel::class.Java)
1
Mircea Nistor