Передача данных из одной viewmodel в другую Android MVVM - PullRequest
5 голосов
/ 26 октября 2019

У меня есть вопрос, связанный с дизайном, ребята.

Итак, я следовал Руководству по архитектуре приложений от Google, чтобы создать свое приложение с использованием Kotlin, MVVM и привязки данных. Я использую компоненты Jetpack (навигация, жилые данные и т. Д.), Как предписано Google.

Проблема заключается в том, что во время разработки мне часто приходится передавать данные из одного фрагмента в другой. Ранее я использовал для создания экземпляра фрагмента и добавления сложных данных, а затем перейти к фрагменту, например:

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
    }
    ....
}

При навигация передача данных между назначением должна бытькак это или для использования модель общего вида , которая также упоминается в той же документации. >>

В общем, вам настоятельно рекомендуется передавать только минимальный объем данных между пунктами назначения. Например, вы должны передать ключ для извлечения объекта, а не сам объект, так как общее пространство для всех сохраненных состояний ограничено в Android. Если вам нужно передать большие объемы данных , рассмотрите возможность использования ViewModel, как описано в разделе «Совместное использование данных между фрагментами».

Это работает.

Проблема заключается в том, что одной из основных причин использования архитектуры является разделение задач;Так что мы можем написать чистый и понятный код. Такое использование sharedviewmodel опровергает эту цель (согласно моему пониманию), так как это приводит к большим классам ViewModel.

Я попытаюсь объяснить проблему с довольно распространенным сценарием.

У меня естьфрагмент со списком данных. Каждый элемент в списке соответствует пользователю. Когда мы нажимаем на элемент, он должен перейти на экран сведений о пользователе, если мы нажимаем на кнопку редактирования, мы должны перейти на экран редактирования, где можно редактировать детали.

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

Так что в этомВ этой ситуации ViewModel будет разделен между этими 3 фрагментами, поскольку данные пользователя должны быть отправлены из класса списка для просмотра и редактирования фрагментов, а совместно используемая ViewModel будет иметь бизнес-логику всех трех фрагментов.

Так что мне это не кажется правильным, потому что ViewModel во многих случаях будет слишком сложным для управления, так как совместное использование будет выглядеть следующим образом:

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

даст тот же экземпляр модели представления.

Мне нужно знать, неверно ли мое понимание этой модели общего вида, если да, пожалуйста, исправьте меня. Если мое понимание верно, пожалуйста, дайте мне знать, как более эффективно управлять моделью представления в таких случаях.

1 Ответ

1 голос
/ 03 ноября 2019

Вы можете иметь несколько ViewModel с в Fragment, поэтому нет необходимости хранить огромный общий ViewModel со всей логикой 3 меньших.

Вы можете создать дополнительныйshared ViewModel, который заботится только о фактических общих данных и сохраняет ваши 3 отдельных фрагмента ViewModel отдельно.

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