Issue
I'm trying to implement circular logic with the Navigation component but I'm concerned that I'm not doing it right and lifecycle methods are unnecessarily being called.
I have 1 activity that has 3 fragments. Navigation between the fragments looks like this: A -> B -> C -> back to A etc..
A and B are regular Fragments while C is a DialogFragment. C has two buttons - Cancel and Done. If Cancel is pressed, a navigation action is called (using findNavController().navigate(<action>)) and the app will show A. If Done is pressed, C is dismissed and the app will show B and the user can then return to A by pressing back. This all works as I expect, however...
My concern is that each route back to A results in different lifecycle methods being called in A. If navigation returns to A after the user accepts C and presses back on B, onCreateView(), onViewCreated(), and onResume() is called by A. BUT, if navigation returns to A after C is cancelled, A calls many more lifecycle methods (onAttach(). onCreate(), onCreateView(), onViewCreated, onResume(), onDestroy(), onDetach()). Why is there a difference? Why is onCreate() being called again in A? Shouldn't it just use the existing instance of A instead of creating a new one?
I can't figure out why it's doing this or if it's even something I should be concerned about. I'm confident that the stack is appropriately managed as the user navigates between fragments because the navigation action between C and A uses the popUpTo and popUpToInclusive attributes (as recommended here in the docs). I've also tried setting the launchSingleTop attribute in the action between C and A but I get the same behaviour (extra lifecycle methods being called in A).
Here is the xml for the C fragment:
<dialog
android:id="@+id/C"
android:name="C"
... >
<action
android:id="@+id/C_to_A"
app:destination="@id/A"
app:popUpTo="@id/A"
app:popUpToInclusive="true" />
</dialog>
I call action C_to_A from C when the user presses the cancel button.
Any help clearing up my confusion would be very welcome.
Solution
An action has two steps:
- popping any destinations set via
popUpTo/popUpToInclusive - Navigating (i.e., creating a new instance of) a destination set via
app:destination
Actions can be any combination of just the pop, just the navigate, or both - the UI in the Navigation Editor when you right click a destination and select New Action will give you each of these options.
Therefore if you want an action that only pops back to a destination you know is on the back stack, then you can remove your app:destination attribute and only pop:
<action
android:id="@+id/C_to_A"
app:popUpTo="@id/A"
app:popUpToInclusive="false" />
Note that by using app:popUpToInclusive="false", you ensure that A will be on the top of the stack after the action is executed.
Answered By - ianhanniballake
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.