Android FragmentManager and Fragment Result API

Viewed 2266

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

2 Answers

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

Related