Search code examples
androidandroid-fragmentsandroid-recyclerviewandroid-viewmodel

Pass data from fragment with recyclerview to the other fragment using ViewModel in android


I have a viewPager inside my application which contains 3 Fragments. First Fragment has a recyclerview on click of the item of recyclerview I pass some data to another fragment which is not the part of viewpager fragements. I am using the latest viewmodel logic to achieve this functionality and as per the steps mentioned by many websites I am doing the following this.

  1. Creating the separate class which extends viewmodel

    class MovieObservable : ViewModel() {
    
    private val selectedMovieID = MutableLiveData<Int>()
    
    fun setSelectedMovieID(id : Int){
        selectedMovieID.value = id 
    }
    
    fun getSelectedMovieID(): MutableLiveData<Int> {
        return selectedMovieID
    }
    
  2. Initialize the viewmodel inside oncreateView Fragment

    private lateinit var mViewModel : MovieObservable
    mViewModel = ViewModelProvider(this).get(MovieObservable::class.java)
    
  3. Now from my RecyclerView I have implemented the click listener and implemented that in my fragment and override the onclick event with the position and value

    override fun onClickNowPlaying(position: Int, view: View, result: Result) {
    
    System.out.println("now playing ID" + result.id)
    mViewModel.setSelectedMovieID(result.id)
    val newFragment = MovieDetailsFragment()
    val transaction = activity?.supportFragmentManager?.beginTransaction()
    transaction?.replace(R.id.mainLayout, newFragment, "NewFragment")
    transaction?.addToBackStack(null)
    transaction?.commit()
    }
    
  4. I add the logic of observing the value in the details fragment which is below

     private lateinit var mViewModel : MovieObservable
     mViewModel = ViewModelProvider(this).get(MovieObservable::class.java)
     mViewModel.getSelectedMovieID().observe(viewLifecycleOwner, Observer {getmydata->
        System.out.println("in the next fragment " + getmydata)
    })
    

So All logic is finished to pass the data from one fragment to another but the problem is I am not getting the data on the details fragment. What is it which I am missing here.


Solution

  • With latest library of ViewModel, it is even easier to create and share ViewModel between Fragments of Activity:

    First add the activity-ktx and fragment-ktx dependencies in your app module's build.gradle:

    dependencies {
    
        // For Activity
        def activity_version = "1.2.0-alpha04"
        implementation "androidx.activity:activity-ktx:$activity_version"
    
        // For Fragment
        def fragment_version = "1.3.0-alpha04"
        implementation "androidx.fragment:fragment-ktx:$fragment_version"
    
    }
    

    Suppose your ViewModel be as:

    class MyViewModel : ViewModel() { }
    

    Then, in your activity:

    class MyActivity : AppCompatActivity() {
    
        // Use the 'by viewModels()' Kotlin property delegate 
        // from the activity-ktx artifact
        val model: MyViewModel by viewModels()
    }
    

    And then, your fragments would have:

    class MyFirstFragment : Fragment() {
    
        // Use the 'by activityViewModels()' Kotlin property delegate
        // from the fragment-ktx artifact
        private val model: MyViewModel by activityViewModels()
    }
    
    class MySecondFragment : Fragment() {
    
        // Use the 'by activityViewModels()' Kotlin property delegate
        // from the fragment-ktx artifact
        private val model: MyViewModel by activityViewModels()
    }