Лучшие практики и шаблоны в ViewModel + Data Binding. ObservableField в ViewModel в порядке?

Просматривая образцы, я увидел 2 подхода к MVVM с использованием компонентов архитектуры Android.

Первый подход:

  1. ViewModel обеспечивает LiveData
  2. Activity подписывается на LiveData
  3. Когда наблюдатель с именем Activity устанавливает данные в ViewModel ObservableField.
  4. Весь ViewModel передается в привязку.
  5. В xml вы просто устанавливаете ObservableField как значение

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        app:visibleGone="@{viewmodel.listLoading}"/>
    
    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swiperefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:refreshing="@{viewmodel.listRefreshing}"
        app:onRefreshListener="@{() -> viewmodel.refreshList()}"
        app:visibleGone="@{!viewmodel.listLoading}">
    

Плюсы. Мне не нужно передавать состояние (например, "загрузка"), так как я обновляю listLoading ObservableField в ViewModel следующим образом:

val listLoading = ObservableBoolean(false)
/** other observable fields go here **/

val list: MutableLiveData<List<Item>> = MutableLiveData()

  fun loadList() {
        listLoading.set(true)
        repo.getList { items ->
            list.value = items
            listLoading.set(false)
        }
    }

Минусы. Есть ли у этого подхода недостатки?

Второй подход:

  1. ViewModel обеспечивает LiveData
  2. Activity подписывается на LiveData
  3. Когда наблюдатель с именем Activity передается в привязку
  4. В привязку передается только нужный объект (pojo).

Плюсы. Какие плюсы у этого подхода?

Минусы: состояние должно возвращаться из ViewModel. В этом примере от Google данные заключены в объект Resource.

Первый подход используется в другом примере приложения от Google< /а>

Я хотел бы знать, каковы плюсы и минусы обоих шаблонов от разработчиков с большим опытом работы с Android Data Binding и Android Arch Components.


comment
Какое-нибудь последнее слово по этому вопросу? Я хочу использовать второй подход, но все еще смущен. Любая помощь??   -  person iMDroid    schedule 29.12.2017


Ответы (1)


Вы должны рассмотреть возможность разделения логики представления с бизнес-логикой.

Поскольку у вас есть ViewModel, использующая привязку данных и AAC для обработки, вы также должны отделить логику внутри вашего представления (макета).

Просто передайте две переменные в макет. Один из них — это VievModel, который обрабатывает бизнес-логику, такую ​​как нажатие кнопки и обработка логики, второй — это представление (фрагмент).

После этого вы можете использовать

app:onRefreshListener="@{() -> yourViewFragment.refreshList()}"

и избегайте «утечки контекста» или неработающего решения, если в настоящее время нет подписки на представление.

Поскольку onRefreshListener привязан к фрагменту, его можно передать внутри вашего фрагмента.

Вы не должны создавать LiveData или ObservableField внутри вашей ViewModel для обработки таких операций, потому что, если вы приостановите и возобновите фрагмент, вы снова будете наблюдать за LiveData. Это также означает, что вы снова получите последние данные.

Пример, который можно использовать в ViewModel:

<Textview ... name="@{viewModel.dataOfYourModel}" onClick="@{viewModel.doNetworkCall}" />

Золотое правило: каждый пакет/импорт, начинающийся с android.*, НЕ должен находиться внутри модели представления, за исключением компонентов android.arch.*.

person Emanuel S    schedule 11.10.2017