2
votes

Comment envoyer des données de l'adaptateur vers ViewModel vers un fragment

Ma structure est comme ça, dans le Fragment j'appelle le ViewModel qui instancie le Adapter

Pour chaque élément de mon RecyclerView , j'ai un bouton que j'écoute

binding.addItem.setOnClickListener(onAddItemClicked(product))

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

Je ne sais pas comment envoyer ces données d'article au fragment, y a-t-il un moyen de faire ça?

Dois-je utiliser l'interface entre Adapter et ViewModel et entre ViewModel et Fragment ?

Ou puis-je utiliser RxEvent & RxBus ?


4 commentaires

pouvez-vous s'il vous plaît élaborer? Je suppose que vous devez ajouter un peu de logique et que vous ajoutez l'auditeur dans l'adaptateur. Que voulez-vous dire par «envoyer les données au fragment»? Que doit faire le fragment avec les données?


Tout d'abord, l'adaptateur doit être instancié dans le fragment et onClickListener doit également y être implémenté. Ensuite, vous n'avez rien à envoyer de RecyclerView à Fragment. Plus tard, vous souhaiterez peut-être avoir une méthode publique dans RecyclerView que vous l'appelez à partir de Fragment lorsque l'utilisateur clique sur l'élément.


Je veux dire par "envoyer des données au fragment", j'ai besoin d'un élément cliqué pour l'envoyer à l'activité principale comme résultat (élément cliqué) à partir du fragment


Je n'instancie pas l'adaptateur dans le fragment mais dans le ViewModel, j'utilise l'architecture MVVM et je ne sais pas si c'est la bonne manière


3 Réponses :


-2
votes

Vous pouvez directement ajouter un élément via la référence ViewModel et vous abonner au changement RxJava EventBus ou LiveData dans votre fragment ou activité


2 commentaires

Comment puis-je ajouter directement l'élément via ViewModel Reference?


Créez une fonction dans ViewModel pour mettre à jour les données et appelez-la.



1
votes

Premièrement pour la navigation entre ViewModel et Fragment -

  • vous pouvez utiliser RxJava PublishSubject pour le rendre public et vous y abonner dans votre Fragment qui peut utiliser les méthodes publiques de ViewModel.
  • ou vous pouvez utiliser une interface, mieux à mon avis que l'utilisation de l'interface, vous utilisez une logique plus simple, beaucoup moins d'erreurs dans ce cas, et c'est aussi un code plus propre car vous pouvez nommer les méthodes dans l'interface comme vous le souhaitez - plus facile à lire.

Deuxième pour la communication entre l'adaptateur et le fragment - vous pouvez utiliser la même stratégie que celle décrite ci-dessus. Dans ce cas, je recommande d'utiliser RxJava, comme d'habitude, il vous suffit de gérer un ou quelques écouteurs de clic (c'est donc par exemple pour observable qui émet des objets de données).
Si vous avez besoin d'exemples de code, envoyez-moi un message dans les commentaires .

MISE À JOUR - il est préférable de créer votre instance d'adaptateur dans View, comme je suppose que vous utilisent le modèle de conception MVVM (où tout le code lié à l'interface utilisateur doit être situé dans le composant View).

Exemple de fragment - Rx de communication d'adaptateur - PublishSubject
Dans votre Adapter

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

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

Et dans votre Fragment

     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()
}

p>


5 commentaires

Merci de votre réponse, oui j'ai besoin d'un exemple pour communiquer entre l'adaptateur et le fragment


vous me conseillez d'utiliser RxJava EventBus pour communiquer entre Adapter et Fragment


Il vous a indiqué que le simple fait d'utiliser une interface est préférable à l'introduction d'un PublishSubject pour cela


En cas de communication entre ViewModel et Fragment, il est préférable d'utiliser l'interface, mais entre Adapter et Fragment (si vous n'avez que 1 ou 2 écouteurs de clic à gérer, je préfère l'utilisateur RxJava).


@GhizlaneLotfi si cette réponse résout vos questions, votez et acceptez-la, sinon posez plus de questions, je vais essayer de vous aider.



-1
votes

RxJava PublishSubject est la meilleure option, je la préférerais et c'est très simple.

J'ai essayé avec recyclerView - Fragment - ViewModel. Certains auront listadapter -> recyclerVire -> Fragment -> ViewModel. J'ai expliqué cela ci-dessous.

Adaptateur de liste

spécifiez votre PublishSubject ici

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

ViewHolder

votre viewHolder déclenche ce PublishSubject.

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

Fragment

abonnez-vous à PublishSubject ici dans le fragment, cela sera automatiquement notifié.

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


0 commentaires