Reputation: 161
hello my problem is the following, I have 2 fragments, one receives with SetFragmentResultListener and another sends with setFragmentResult
The problem is that setFragmentResult does not work inside an OnClickListener but it does work outside
Parent
setFragmentResultListener("scannedCode") { requestKey, bundle ->
val result = bundle.getString("code")
Log.i("MYLOG-find","$result")
}
Child - It Work
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_scan, container, false)
setFragmentResult("scannedCode", bundleOf("code" to "pedro"))
return view
}
Child - It doesn't Work
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_scan, container, false)
view.textView2.setOnClickListener {
setFragmentResult("scannedCode", bundleOf("code" to "pedro"))
}
return view
}
Upvotes: 16
Views: 19976
Reputation: 1039
Call setFragmentResultListener
in onViewCreated
method of your parent fragment.
Because according to the source code of FragmentManager
, the FragmentResultListener
would be removed when parent fragment's onDestroyView
called, so when you go back to parent fragment, you should register the listener again in order to make sure it is called after parent fragment start.
Upvotes: 0
Reputation: 337
In my case sending result from pushed fragment to presenting, I need to call: requireActivity().onBackPressed()
, then setFragmentResult()
.
Upvotes: 0
Reputation: 181
In the case of passing data from Child to Parent fragment, using the childFragmentManager
is the key when setting the resultListener on the parent fragment.
onCreate()
):childFragmentManager.setFragmentResultListener("requestKey", this ) { requestKey, bundle ->
val resultReceived = bundle.getString("bundleKey")
// do something with the result
// ...
}
val resultToBeSent = "result"
setFragmentResult("requestKey", bundleOf("bundleKey" to resultToBeSent))
More useful information about the communication between fragments can be found in this medium article: The modern way to pass data between fragments and of course in the official Android documentation: Communicating with fragments.
Upvotes: 13
Reputation: 648
As per @ianhanniballake's answer, I went a bit further, because I had a similar problem, and read the documentation he referred (specially, the Receive results in the host activity section). One of the keys in making inter-fragment communication (parent-child) is to use activity's supportFragmentManager
methods to perform the information exchange. Example:
requireActivity().supportFragmentManager
.setFragmentResultListener("whatever_id_you_use", viewLifecycleOwner) {
// Your code for listener
}
requireActivity().supportFragmentManager
.setFragmentResult("whatever_id_you_use", bundle_with_results)
"whatever_id_you_use"
is the requestKey depicted in documentation, which is the index the activity will look for when assigning a listener to its result. Doing this way should keep the listeners in sync with the lifecycle, while simplifying own listener's implementation.
Upvotes: 25
Reputation: 200080
When you use the Navigation Component, the previous fragment is stopped when you navigate to a new fragment. As per the Fragment Result API guide:
If you call
setFragmentResult()
more than once for the same key, and if the listener is notSTARTED
, the system replaces any pending results with your updated result. If you set a result without a corresponding listener to receive it, the result is stored in theFragmentManager
until you set a listener with the same key. Once a listener receives a result and fires theonFragmentResult()
callback, the result is cleared. This behavior has two major implications:
- Fragments on the back stack do not receive results until they have been popped and are
STARTED
.- If a fragment listening for a result is
STARTED
when the result is set, the listener's callback is then fired immediately.
So it is expected that you do not get any calls to your fragment result listener until you pop back to that fragment and it becomes STARTED
again.
Upvotes: 6