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.