デザイン関係の質問があります。
したがって、私は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に対する私の理解が間違っているかどうかを知る必要があります。間違っている場合は修正してください。私の理解が正しければ、そのような場合にビューモデルをより効率的に管理する方法を教えてください。
ViewModel
には複数のFragment
sを含めることができるため、3つの小さいロジックをすべて備えた巨大な共有ViewModel
を保持する必要はありません。
実際の共通データのみを対象とする追加の共有ViewModel
を作成し、3つの個別のフラグメント固有のViewModel
sを個別に保持できます。
sharedModel = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.Java]
} ?: throw Exception("Invalid Activity")
localViewModel = ViewModelProviders.of(this).get(LocalViewModel::class.Java)