6

I have an app structured in MVVM. I have different fragments within the same activity. Each fragment has its own ViewModel and all data are retrieved from a REST API.

In FragmentA, there is a RecyclerView that lists X class instances. I want to set OnClickListener on the RecyclerView and I want to pass related X object to FragmentB when an item clicked in the RecyclerView. How can I achieve this?

Ryan M
  • 18,333
  • 31
  • 67
  • 74
Mehmed
  • 2,880
  • 4
  • 41
  • 62
  • 1
    Provide your code whatever you have tried so far. – Rajnish suryavanshi Aug 21 '19 at 07:54
  • Just basic project with the info provided, this could be more to the point rather than sharing 10 files, which causes reader to lost interest and time. I can link to the project though. – Mehmed Aug 21 '19 at 08:46
  • Use java interface, see links for "how to pass data from 1 fragment to another". It has nothing to do with MVVM architecture. Viewmodel is to hold dataset. If you had use viewmodel for your activity, then you could have skip interface part. – Rishabh Jain Aug 21 '19 at 08:48
  • I can wrap ListAdapter and send a callback as parameter from the FragmentA. This callback can use navController() and send selected item to FragmentB. I will try. – Mehmed Aug 21 '19 at 09:17
  • 2
    The the most convenient way of solving this is to use an interface in your adapter class. This is what I have also used in one of my [repos](https://github.com/alexmamo/FirebaseApp/blob/master/app/src/main/java/ro/alexmamo/firebaseapp/main/products/ProductsAdapter.java) ;) – Alex Mamo Aug 21 '19 at 10:15
  • @Mehmed your problem is you want to pass data when row click in recyclerview to another fragment?? did you use Kotlin? – EL TEGANI MOHAMED HAMAD GABIR Sep 02 '19 at 06:47
  • Yes for both... – Mehmed Sep 02 '19 at 07:06
  • @Mehmed are you using data binding? – Zafer Celaloglu Sep 02 '19 at 07:24
  • Yes, I do. I am just not sure where to implement it. The scenario is that when you clicked an item in recyclerview in A, I want to add it to a livedata list in viewmodel of B. This viewmodel of B is actually a shared one, can be thought as your cart during shopping. – Mehmed Sep 02 '19 at 07:47
  • ok then I'm posting my answer along with my GitHub repository that I applied this in MVVM arch. structure – Zafer Celaloglu Sep 02 '19 at 08:51

2 Answers2

6

How I imagine it is the following.

The Fragment passes a listener object to the adapter, which in turn passes it to the ViewHolders

Here is a quick sketch of how it should look like

class Fragment {
    val listener = object: CustomAdapter.CustomViewHolderListener() {
        override fun onCustomItemClicked(x: Object) {}

    }

    fun onViewCreated() {
        val adapter = CustomAdapter(listener)
    }
}
---------------
class CustomAdapter(private val listener: CustomViewHolderListener) {
    val listOfXObject = emptyList() // this is where you save your x objects

    interface CustomViewHolderListener{
        fun onCustomItemClicked(x : Object)
    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        holder.itemView.setOnClickListener {
            listener.onCustomItemClicked(listOfXObject[position])
        }
    }
}

Here are some articles that might help you get the general gist of the things. They don't answer your question directly though

Hope it is helpful link 1 link 2

john-salib
  • 724
  • 1
  • 12
  • 27
4

if you're using data binding you need to pass your view(which is Fragment in your case) into the layout via adapter class and you need to import your view in layout file to be able to call view's method

android:onClick="@{() -> view.onXXXClick(item)}"

pass your current model class which is item into this new method and then create onXXXClick method in your view and do whatever you wish.

if you will be doing view related operations such as navigation from one fragment to another or starting a service you should create above function in your view, if you're doing network or db related operations it should be in your ViewModel

you can check out my GitHub repository to understand better.

Zafer Celaloglu
  • 1,438
  • 1
  • 17
  • 28