Search code examples
androidviewmodelandroid-dialogfragment

How to send data from DialogFragment to Fragment using viewmodel


I'm trying to send data from DialogFragment to Fragment using ViewModel but it seems both fragment and Dialog fragment are referencing different instances of ViewModel. so I can't access data . Is there any way I can fix this issue? thanks

Here is my Fragment

@AndroidEntryPoint
class FragmentToReceiveData:BaseFragment(R.layout.fragment_1){
   private val viewModel: AddScheduleViewModel by viewModels()
   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      Log.d(TAG, "onViewCreated: $viewModel")   // will print ...MyViewModel@62274cc  

      viewModel.dataFromDialog.observe(viewLifecycleOwner){
         //nothing happens
      } 
   }
   .
   .
   .
   private fun openDialog(){
    val action=FragmentToReceiveDataDirections.actionFragmentToReceiveDataToExampleDialog()
    findNavController().navigate(action)
    //exampleDialog.show(requireActivity().supportFragmentManager, "alarmDialog") //same issue      
   }
   
}

Here is ViewModel:

class MyViewModel @ViewModelInject constructor(){
   var dataFromDialog=MutableLiveData<SomeClass>()
   
   fun saveDataFromDialog(data:SomeClass){
     dataFromDialog.value=data      
   }
 }

Here is my DialogFragment

@AndroidEntryPoint
class ExampleDialog:DialogFragment() {
  val viewModel:MyViewModel by viewModels()
  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    Log.d(TAG, "onCreateDialog: $viewModel")   // will print ...MyViewModel@125436
    .
    .
    .
    viewMode.saveDataFromDialog(data)
  }
}

P.S: I'm using single activity architecture, So I'm not sure if activityViewModels() is a good idea


Solution

  • in order to share ViewModel between fragments, you can use activityViewModels(). for instance,

    class SharedViewModel : ViewModel() {
        ...
    }
    
    class MasterFragment : Fragment() {
    
        // Use the 'by activityViewModels()' Kotlin property delegate
        // from the fragment-ktx artifact
        private val model: SharedViewModel by activityViewModels()
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            ...
        }
    }
    
    class DetailFragment : Fragment() {
    
        // Use the 'by activityViewModels()' Kotlin property delegate
        // from the fragment-ktx artifact
        private val model: SharedViewModel by activityViewModels()
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            ...
        }
    }
    

    please read more in the android documentation here: https://developer.android.com/topic/libraries/architecture/viewmodel#sharing