Как отправить данные из DialogFragment во фрагмент с помощью viewmodel

#android #viewmodel #android-dialogfragment

#Android #viewmodel #android-dialogfragment

Вопрос:

Я пытаюсь отправить данные из DialogFragment во фрагмент с помощью ViewModel, но, похоже, как фрагмент, так и фрагмент диалога ссылаются на разные экземпляры ViewModel. поэтому я не могу получить доступ к данным. Есть ли какой-либо способ исправить эту проблему? Спасибо

Вот мой фрагмент

 @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      
   }
   
}
  

Вот ViewModel:

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

Вот мой 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: Я использую архитектуру single activity, поэтому я не уверен, что activityViewModels() — хорошая идея

Ответ №1:

чтобы разделить ViewModel между фрагментами, вы можете использовать activityViewModels() . например,

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

пожалуйста, прочитайте больше в документации Android здесь:https://developer.android.com/topic/libraries/architecture/viewmodel#sharing

Комментарии:

1. Но можно ли использовать activityViewModels в архитектуре single activity?

2. я думаю, что это нормально, поскольку этот метод используется только для получения ссылки на ViewModel, привязанный к родительской активности фрагмента