Reputation: 990
How can be that a fragment F which uses the new Fragment Result API to get results from 2 other fragments: A, B gets the result from A but not from B because B has a different parent FragmentManager (and I don't know why) ? How could be something like that ? 2 fragments called in the same way but they end up having same Activity but different FragmentManager ? The function calls are the following:
//THIS DOESN'T WORK. THE LISTENER IS NOT CALLED AFTER THE RESULT IS SET
private fun navigateToItemLocation() {
setFragmentResultListener(REQUEST_LOCATION_KEY) { s: String, bundle: Bundle ->
val locationId = bundle.getParcelable<ParcelUuid>(LOCATION_ID)!!.uuid
viewModel.viewModelScope.launch(Dispatchers.IO) {
val location = LocationRepository().get(locationId)!!
changeItemLocation(location)
}
}
val action = ItemRegistrationPagerHolderDirections.actionNavItemRegistrationPagerToNavStockLocationSelection()
findNavController().navigate(action)
}
//THIS WORKS FINE:
private fun navigateToItemDetails(item: Item2) {
setFragmentResultListener(SELECTED_ITEM_KEY) { s: String, bundle: Bundle ->
val propertySetId = bundle.getParcelable<ParcelUuid>(SELECTED_ITEM_SET_ID)!!.uuid
clearFragmentResultListener(SELECTED_ITEM_KEY)
viewModel.viewModelScope.launch(Dispatchers.IO) {
val repository = PropertySetRepository()
val propertySet = repository.get(propertySetId)!!
val propertySetInfo = ItemFactory.loadPropertySetInfo(propertySet)
withContext(Dispatchers.Main) { setPackageCode(null) }
selectItem(item.item, propertySetInfo, item.description, null)
}
}
val action = ItemRegistrationPagerHolderDirections.actionNavItemRegistrationToNavStockItemDetails(ParcelUuid(item.item.id), true)
findNavController().navigate(action)
}
Both fragments A and B are in a separate Dynamic Feature. The only single problem I have is that when the following function is called:
fun onSelect() {
viewModel.pickedLocation.value = (viewModel.selectedLocation as? LocationExt2?)?.location
val result = bundleOf(Pair(LOCATION_ID, ParcelUuid(viewModel.pickedLocation.value!!.id)))
setFragmentResult(REQUEST_LOCATION_KEY, result)
findNavController().popBackStack()
}
setFragmentResult(REQUEST_LOCATION_KEY, result)
Doesn't produce any result because the FragmentManager is not the same of the calling Fragment. The same method in fragment A which is:
private fun onSetSelected(id: UUID) {
propertySets.removeObservers(viewLifecycleOwner)
adapter.tracker = null
setFragmentResult(SELECTED_ITEM_KEY, bundleOf(Pair(SELECTED_ITEM_SET_ID, ParcelUuid(id))))
findNavController().popBackStack()
}
As a temporarily workaround I replaced the call to Fragment's FragmentManager with Activity.supportFragmentManager.setFragmentResultListener. It works but still I do not understand why fragments A and B behave differently...
Upvotes: 3
Views: 4930
Reputation: 305
Check this blog article for the principles and rules with Fragment Result API on medium: https://medium.com/@FrederickKlyk/state-of-the-art-communication-between-fragments-and-their-activity-daa1fe4e014d
Only one listener can be registered for a specific request key.
If more than one listener is registered on the same key, the previous one will be replaced by the newest listener.
Upvotes: 0
Reputation: 79
Check that fragment where you listen for fragment result and fragment where you set the result are in the same fragment manager.
Common case where this would happen is if you are using Activity.getSupportFragmentManager()
or Fragment.getParentFragmentManager()
alongside Fragment.getChildFragmentManager()
.
Upvotes: 4