Могу ли я передать ViewModel адаптеру RecyclerView и наблюдать за LiveData?

Я начал внедрять MVVM, и я не знаю, является ли использование ViewModel внутри моего Adapter хорошей практикой или антипаттерном.

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

Но я наблюдаю за colorSelected в двух местах:

  • В Fragment для изменения цвета фона
  • В Adapter для отображения какой цвет выбран

Итак, правильно ли я использую MVVM, когда передаю и наблюдаю за ViewModel на Adapter?

вы нашли эффективное решение своей проблемы?

Aman Grover 13.05.2020 13:50

вроде бы, но меня это не устраивает, я знаю, что если я добавлю сюда, никто не предложит решение. У тебя есть решение?

AndroidStorm 27.05.2020 08:40
28
2
5 374
2

Ответы 2

Я не уверен, что это хороший шаблон, но с этим есть одна проблема: таким образом ваш адаптер привязан к вашей ViewModel, что означает, что вы не можете повторно использовать его с другой ViewModel на другом экране. С другой стороны, гораздо проще работать без этих дополнительных обратных вызовов от recyclerView, которые упрощают реализацию. Я думаю, что «лучше» использовать обратные вызовы, но «проще» передать ViewModel (я думаю, CG должна справиться с этим без проблем)

когда вы сказали: «Сейчас я не уверен», это потому, что вы ищете лучший ответ?

AndroidStorm 26.10.2018 21:53

Кстати спасибо

AndroidStorm 26.10.2018 21:53

@AndroidStorm Я тоже искал ответ, но основная причина в том, что один программист скажет, что лучше сделать код более эластичным, увеличив объем работы, а другой скажет: «Зачем мне делать более эластичный код, если для этого требуется гораздо больше работы? ". Думаю, это зависит от проекта :)

Janusz Hain 27.10.2018 18:22

Я только что нашел статью, в которой говорится, что что-то вроде Recyclerview - это представление, не имеющее никакого отношения к вашему проекту. Поэтому в нем не должно быть ссылки на ваши модели. Но все еще ищу правильный ответ.

AndroidStorm 19.04.2019 00:04

@AndroidStorm Я использовал несколько шаблонов, думаю, ни один из них не является неправильным. Вопрос выбора. На данный момент я передаю интерфейс для обратного вызова адаптера, и таким образом я могу повторно использовать адаптер на нескольких экранах. Я могу расширить интерфейс в Fragment или ViewModel (так что я могу также передать ViewModel в конструкторе). Я использую это плюс привязку данных и отлично работает - например, я хочу "лайкнуть" пост - интерфейс использует обратный вызов, чтобы сообщить об этом фрагменту, фрагмент позволяет обработать вызов ViewModel, а из вызова я меняю информацию о модели поста (количество лайков и т. д.) И это отражается с помощью привязки данных в адаптере

Janusz Hain 19.04.2019 09:07

Что ж, я искал решение этого вопроса, но, наконец, должен справиться сам. Я хотел бы разместить здесь свою мысль для обсуждения.

Проще говоря, передача экземпляра viewModel адаптеру, на мой взгляд, не изящна. Вместо этого я рекомендую вам переопределите метод onAttachedToRecyclerView вашего RecyclerViewAdapter, чтобы получить вашу модель просмотра:

public class YoursAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
......
private YoursViewModel viewModel;
......
    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        if (viewModel==null){
            viewModel=new ViewModelProvider((ViewModelStoreOwner) recyclerView.getContext()).get(YoursViewModel.class);
        }
    }
......
}

Почему я считаю это решение хорошим?

1. Сама модель ViewModel не имеет ничего общего с контекстами. Но для создания экземпляра ViewModel нужен контекст.

2 、 Какой контекст вы выберете? Контекст recyclerView, поскольку вы хотите что-то сделать внутри адаптера, а адаптер связан с recyclerView. Почему я переопределяю onAttachedToRecyclerView? Поскольку этот обратный вызов предоставляет ссылку recyclerView и выполняется только один раз.

3. Пока контекст recyclerView жив, ViewModel жив. Это то, что ты хочешь? Если ответ «Да», то разумно создать экземпляр ViewModel на основе контекста recyclerView.

4. У вас есть ViewModel во фрагменте. Разумно ли в адаптере создавать новую? Да. Одно из преимуществ ViewModel - обмен данными, пока они занимаются одной и той же деятельностью.

5. На самом деле вам не нужно наблюдать за живыми данными внутри адаптера (который снова требует контекста), если вы правильно спроектировали ViewModel. В основном вы просто наблюдаете живые данные на фрагменте. Ваша ViewModel внутри адаптера просто отвечает за изменение данных, не заботясь о том, как данные изменились, то есть делать yourViewModelInstance.post_value_to_liveData_and return_it().observe() на фрагменте и делать yourViewModelInstance.post_value_to_liveData_and return_it() внутри адаптера.

Другие вопросы по теме