preface
Fragment 1.3.0- Alpha04 has been released with a number of changes, including new ways of passing data between fragments
API changes
First, let’s look at API changes
startActivityForResult()
/onActivityResult()
和requestPermissions()
/onRequestPermissionsResult()
deprecatedprepareCall()
renameregisterForActivityResult()
target fragment API
Be abandoned
The Activity Result API is on top
Since the ActivityResult API is provided to replace the onActivityResult mechanism, So the fragments startActivityForResult ()/onActivityResult () and requestPermissions ()/onRequestPermissionsResult was mark deprecated () method
It’s time to drop onActivityResult!
The article is very detailed and will not be repeated here
PrepareCall rename
It is worth noting that the place is prepareCall () was named registerForActivityResult ()
❝
Note: apis can be added, removed, or changed while the version is in Alpha state. The Alpha version is therefore not suitable for production use
❞
Target Fragment API deprecated
The Target Fragment API has long been deprecated
A Target fragment requires direct access to an instance of another fragment, which is dangerous because you don’t know what state the target fragment is in. And the Target fragment does not support Navigation
So what’s a cleaner way to pass data between fragments?
A new way to pass data between fragments
As mentioned earlier, you can use the Target Fragment API in the same FragmentManager to pass data between fragments, but this approach requires direct access to the target fragment instance, which is dangerous. Because the state of the target fragment is unknown
So an API is officially available that allows you to set results on a fragment and use that result for the appropriate life of the fragment.
This method of passing data applies to the fragment in DialogFragment and Navigation
This change also includes the -ktx extension to ensure that kotlin users can pass FragmentResultListener as a lambda
Source code analysis
As usual, let’s follow the official Commit log to see how the official implementation of this feature works
First, we add an abstraction like FragmentResultOwner that handles fragment results with two methods inside
- setResult
- setResultListener
The former is used to send data and the latter to receive data
The implementation class is FragmentManager
Let’s look at a concrete implementation of the FragmentManager two methods
public final void setFragmentResultListener(@NonNull final String requestKey,
@NonNull final LifecycleOwner lifecycleOwner,
@Nullable final FragmentResultListener listener) {
// Remove the listener corresponding to the requestKey if the listener is empty
if (listener == null) {
mResultListeners.remove(requestKey);
return;
}
// Return when the fragment is in the DESTROYED state to avoid exceptions
final Lifecycle lifecycle = lifecycleOwner.getLifecycle();
if (lifecycle.getCurrentState() == Lifecycle.State.DESTROYED) {
return;
}
Observe the lifecycle, fragment started receives callbacks, and destroyed removes callbacks
LifecycleEventObserver observer = new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_START) {
// once we are started, check for any stored results
Bundle storedResult = mResults.get(requestKey);
if(storedResult ! =null) {
// if there is a result, fire the callback
listener.onFragmentResult(requestKey, storedResult);
// and clear the result
setFragmentResult(requestKey, null);
}
}
if (event == Lifecycle.Event.ON_DESTROY) {
lifecycle.removeObserver(this);
mResultListeners.remove(requestKey);
}
}
};
lifecycle.addObserver(observer);
mResultListeners.put(requestKey, new LifecycleAwareResultListener(lifecycle, listener));
}
Copy the code
The above is the source code of this part
❝
One thing to note here is that the Fragment Result API is based on the same FragmentManager
❞
conclusion
Officials have been working on making the Fragment API more usable
Ian Lake in Fragments could: Past, Present, and Future (Android Dev Summit ’19) addresses the issue of communication between fragments. In the Future, fragments will integrate the lifecycle of both the fragment itself and its internal view. Support for multiple return stacks for the same FragmentManager
When I see the Fragment Result API, I suddenly have an idea. Is it a method to reset the state after Navigation jump return if it is applied to Navigation?
Do you have any thoughts in the comments section
About me
I am a Fly_with24
-
The Denver nuggets
-
Jane’s book
-
Github