Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation Component prevent to recreate fragment on back press

I'm using the Jetpack Navigation Component in my project with a single activity and some fragments.

I have a fragment with a list that fills from server side. I call getDataFromServer on the onViewCreated method then, when a user clicks on an item, a new fragment shows.

The problem is that when I press the back button, onViewCreated is called again in my list fragment.

So, how can I prevent my first fragment from recreating again? I don't want unnecessary onViewCreated calls.

like image 369
FarshidABZ Avatar asked Feb 06 '19 12:02

FarshidABZ


People also ask

How to stop recreating fragment in android?

Calling setRetainInstance(true) will prevent the Fragment from being re-created.

What is popUpToInclusive?

When navigating back to destination A, we also popUpTo A, which means that we remove B and C from the stack while navigating. With app:popUpToInclusive="true" , we also pop that first A off of the stack, effectively clearing it.


2 Answers

Of course, we can not prevent calling oncrateView, but there is a simple way. Instead of calling view.loadData() in onCreateView or other lifecycle methods we can call it while initializing ViewModel

this article helped me to know ViewModel better 5 common mistakes when using Architecture Components

Update:

The current navigation component (V 2.3.0) doesn't support this feature, it always kills the fragment while navigating to another fragment. Imagine you have google map in Fragment A so each time you returns to the Fragment it initialized again and the camera moves to the user location!! (what a bad idea).

So the best way is not to use the navigation component if you have the same issue.

Navigation, Saving fragment state, GitHub issue

Update 2:

In some cases like Filters or pagination, we can use Transformations like switchMap in our ViewModel instead of getting data in init function.

Update 3:

If you have to call a function to load data from a source, there are lots of ways to prevent call that function again, the first and easiest way is instead of calling getData() in your view, do it your ViewModel init function. the second one is using lazy variables and another one is using SwitchMap on livedata. for more information you can find all solutions here

like image 158
FarshidABZ Avatar answered Oct 27 '22 09:10

FarshidABZ


Maybe you have activate the graph.

app:popUpTo="@+id/nav_fingerprint_capture"
app:popUpToInclusive="true"
like image 37
Eduardo Yurén Avatar answered Oct 27 '22 09:10

Eduardo Yurén