title: Shared ViewModel to help communication between fragments and parent activity
body: <p>While Navigation component of JetPack looks pretty promising I got to a place where I could not find a way to implement something I wanted.</p>
  
  <p>Let's take a look at a sample app screen:</p>
  
  <p><a href="https://i.stack.imgur.com/HvKth.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/HvKth.png" alt=" "></a></p>
  
  <p>The app has one main activity, a top toolbar, a bottom toolbar with fab attached.
  There are 2 challenges that I am facing and I want to make them the right way.</p>
  
  <p><strong>1. I need to implement fragment transactions in order to allow replacing the fragment on the screen, based on the user interaction.</strong> 
  There are three ways I can think of and have this implemented:</p>
  
  <ul>
  <li>the callbacks way. Having a interface <code>onFragmentAction</code> callback in fragment and have activity implement it. So basically when user presses a button in <code>FragmentA</code> I can call <code>onFragmentAction</code> with params so the activity will trigger and start for example transaction to replace it with <code>FragmentB</code></li>
  <li>implement <code>Navigation</code> component from JetPack. While I've tried it and seems pretty straightforward, I had a problem by not being able to retrieve the current fragment.</li>
  <li>Use a shared <code>ViewModel</code> between fragment and activity, update it from the fragment and observe it in the activity. This would be a "replacement" of the callbacks</li>
  </ul>
  
  <p><strong>2. Since the <code>FAB</code> is in the parent activity, when pressed, I need to be able to interact with the current visible fragment and do an action. For instance, add a new item in a recyclerview inside the fragment. So basically a way to communicate between the activity and fragment</strong>
  There are two ways I can think of how to make this</p>
  
  <ul>
  <li>If not using <code>Navigation</code> then I can use <code>findFragmentById</code> and retrieve the current fragment and run a public method to trigger the action. </li>
  <li>Using a shared 'ViewMode' between fragment and activity, update it from activity and observe it in the fragment.</li>
  </ul>
  
  <p>So, as you can see, the recommended way to do navigation would be to use the new 'Navigation' architecture component, however, at the moment it lacks a way to retrieve the current fragment instance so I don't know how to communicate between the activity and fragment. 
  This could be achieved with <code>shared ViewModel</code> but here I have a missing piece: I understand that fragment to fragment communication can be made with a shared ViewModel. I think that this makes sense when the fragments have something in common for this, like a Master/Detail scenarion and sharing the same viewmodel is very useful. </p>
  
  <p>But, then talking between activity and <strong>ALL</strong> fragments, how could a shared <code>ViewModel</code> be used? Each fragment needs its own complex ViewModel. Could it be a <code>GeneralViewModel</code> which gets instantiated in the activity and in all fragments, together with the regular fragment viewmodel, so have 2 viewmodels in each fragment. </p>
  
  <p>Being able to talk between fragments and activity with a viewmodel will make the finding of active fragment unneeded as the viewmodel will provide the needed mechanism and also would allow to use <code>Navigation</code> component.</p>
  
  <p>Any information is gladly received.   </p>
  
  <p>Later edit. Here is some sample code based on the comment bellow. Is this a solution for my question? Can this handle both changes between fragments and parent activity and it's on the recommended side.</p>
  
  <pre><code> private class GlobalViewModel ():ViewModel(){
  
        var eventFromActivity:MutableLiveData&lt;Event&gt;
        var eventFromFragment:MutableLiveData&lt;Event&gt;
  
  
        fun setEventFromActivity(event:Event){
            eventFromActivity.value = event
        }
  
        fun setEventFromFragment(event:Event){
            eventFromFragment.value = event
        }
  
   } 
  </code></pre>
  
  <p>Then in my activity </p>
  
  <pre><code>class HomeActivity: AppCompatActivity(){
  
     onCreate{
         viewModel = ViewModelProviders.of(this, factory)
                  .get(GlobalViewModel::class.java)
  
          viewModel.eventsFromFragment.observe(){
             //based on the Event values, could update toolbar title, could start
             // new fragment, could show a dialog or snackbar
          ....
          }   
  
       //when need to update the fragment do 
       viewModel.setEventFromActivity(event)
     }
  }
  </code></pre>
  
  <p>Then in all fragments have something like this</p>
  
  <pre><code>class FragmentA:Fragment(){
  
    onViewCreated(){
  
         viewModel = ViewModelProviders.of(this, factory)
                  .get(GlobalViewModel::class.java)
  
          viewModel.eventsFromActivity.observe(){
             // based on Event value, trigger a fun from the fragment 
          ....
          }
  
          viewModelFragment = ViewModelProviders.of(this, factory)
              .get(FragmentAViewModel::class.java)
  
          viewModelFragment.some.observe(){
          ....
          }   
  
    //when need to update the activity do 
       viewModel.setEventFromFragment(event)      
    }
  
  }
  </code></pre>