Как отправить данные из адаптера в ViewModel во фрагмент

Моя структура такая: в Fragment я вызываю ViewModel, который создает экземпляр Adapter

Для каждого пункта моего RecyclerView у меня есть кнопка, которую я слушаю

binding.addItem.setOnClickListener(onAddItemClicked(product))

private fun onAddToQuoteClicked(product: Product): View.OnClickListener {
    return View.OnClickListener {
        // TODO add item
    }
}

Я не знаю, как отправить данные этого элемента во фрагмент, есть ли способ сделать это?

Должен ли я использовать интерфейс между Adapter и ViewModel и между ViewModel и Fragment?

Или я могу использовать RxEvent и RxBus?

не могли бы вы уточнить? Я думаю, вам нужно добавить некоторую логику, и вы добавляете прослушиватель в адаптер. Что вы имеете в виду, говоря «отправить данные во фрагмент»? Что фрагмент должен делать с данными?

Gregorio Palamà 28.05.2019 09:04

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

gts13 28.05.2019 09:14

Я имею в виду «отправить данные во фрагмент», мне нужно щелкнуть элемент для отправки в основное действие в качестве результата (выбранный элемент) из фрагмента

Ghizlane Lotfi 28.05.2019 09:30

Я не создаю экземпляр адаптера во фрагменте, но в ViewModel я использую архитектуру MVVM, и я не знаю, правильно ли это

Ghizlane Lotfi 28.05.2019 09:32
3
4
4 060
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Как я могу напрямую добавить элемент через ViewModel Reference?

Ghizlane Lotfi 28.05.2019 09:33

Создайте функцию в ViewModel для обновления данных и вызовите ее.

Vishal Pawar 28.05.2019 11:58
Ответ принят как подходящий

Сначала для навигации между ViewModel и Fragment -

  • вы можете использовать RxJava Опубликовать Тему, сделать его общедоступным и подписаться на него в своем фрагменте, который может использовать общедоступные методы ViewModel.
  • или вы можете использовать интерфейс, на мой взгляд, лучше, так как используя интерфейс, вы используете более простую логику, в этом случае гораздо меньше ошибок, а также это более чистый код, так как вы можете называть методы в интерфейсе как хотите - легче читать.

Во-вторых, для связи между адаптером и фрагментом — вы можете использовать ту же стратегию, что описана выше. В этом случае я рекомендую использовать RxJava, так как обычно вам просто нужно обработать один или несколько прослушивателей кликов (например, для наблюдаемых, которые испускают некоторый объект данных).
Если вам нужны примеры кода, напишите мне в комментариях.

ОБНОВИТЬ — лучше создать экземпляр адаптера в представлении, поскольку я предполагаю, что вы используете шаблон проектирования MVVM (где весь код, связанный с пользовательским интерфейсом, должен находиться в компоненте представления).

Фрагмент примера — связь адаптера Rx — PublishSubject
В вашем Адаптер

     private val publisher = PublishSubject.create<Product>()
fun getObservableProductItem(): Observable<Product> = publisher.hide()

binding.addItem.setOnClickListener(onAddItemClicked(product))
private fun onAddToQuoteClicked(product: Product): View.OnClickListener {
    return View.OnClickListener {
        publisherRideItem.onNext(items[adapterPosition])
    }
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
    publisherRideItem.onComplete()
}

А в вашем Фрагмент

 compositeDisposable.add(adapter.getObservableProductItem().subscribe {
            //TODO do whatever you want with it
        })   

  override fun onDestroy() {
    super.onDestroy()
    compositeDisposable.clear()
}

Спасибо за ваш ответ, да, мне нужен пример для связи между адаптером и фрагментом

Ghizlane Lotfi 28.05.2019 09:40

вы советуете мне использовать RxJava EventBus для связи между адаптером и фрагментом

Ghizlane Lotfi 28.05.2019 09:43

Он посоветовал вам, что просто использовать интерфейс лучше, чем вводить PublishSubject для этого.

EpicPandaForce 28.05.2019 09:44

В случае связи между ViewModel и Fragment лучше использовать интерфейс, а между Adapter и Fragment (если у вас есть только 1 или 2 прослушивателя кликов для обработки, я предпочитаю пользователя RxJava).

mr.kostua 28.05.2019 09:51

@GhizlaneLotfi, если этот ответ решит ваши вопросы, проголосуйте и примите его, в противном случае задайте больше вопросов, я постараюсь вам помочь.

mr.kostua 28.05.2019 10:29

RxJava PublishSubject — лучший вариант, я бы предпочел его, и он очень прост.

Я пробовал с recyclerView - Fragment - ViewModel. У некоторых будет listadapter -> recyclerVire -> Fragment -> ViewModel. Я объяснил это ниже.

Список адаптеров

укажите здесь свой PublishSubject

class myapadter : ListAdapter
{
 object RxBus {
    val itemClickStream: PublishSubject<View> = PublishSubject.create()
}
}

ViewHolder

в вашем viewHolder вызывает этот PublishSubject.

class myViewholder : RecyclerView.ViewHolder(itemView)
{
            itemView.myButton.setOnClickListener {
               v -> RxBus.itemClickStream.onNext(v) }
}

Фрагмент

подпишитесь на PublishSubject здесь, во фрагменте, это автоматически получит уведомление.

myapadter.RxBus.itemClickStream.subscribe(){ v ->
            if (v.id == R.id.myButton) {
              viewModel.callyourfunction()
            }

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

Похожие вопросы

Не могу перезагрузить приложение React-native на физическом устройстве Android
Как объявить устаревшим A CustomView и показать устаревание в макете XML
Как использовать переменную Object Observable внутри другой функции подписки Observable – RxJava
Переполнение пользовательского интерфейса, когда клавиатура открывается в трепете
Почему мое приложение открывает неправильную папку в диалоговом окне файлового менеджера?
Событие щелчка Android EditText запускается во второй раз
Намерение не работает для перемещения фрагмента в действие
Пользовательское ограничение макета Recycleview меняется для каждого раздутого представления, вызывающего проблемы
Нативное приложение React аварийно завершает работу в режиме выпуска со следующей ошибкой: ноль не является объектом (оценка 's.drawer._root')
Не удалось разрешить все файлы для конфигурации ':app:debugCompileClasspath'. > Не удалось найти com.android.support:support-v4:28.1.0