I have an app that has one Activity that loads fragments… on initial startup it loads fragment A. From A the user can navigate to fragment B; and from B navigate to fragment C. Each time a fragment is replaced I do addToBackStack. The back button navigates as one would expect, C to B to A, and if you press back again the app exits.
I’m also using a Dropbox datastore to save all my app’s data so I can move seamlessly between devices and have all my data synced. This seems to be working well. As part of my data I store which fragment was last displayed. Now when my app starts on a second device it correctly displays the most recently opened fragment. This works fine, however, I no longer have a backstack. For example, if the app is showing fragment C device one and then I start the app on device two, as expected fragment C is shown on device two. But when I press the back button, the app exits instead of showing fragment B. (Which makes sense since on device two the app only loaded fragment C.)
So my question: How do I pre-populate my baskstack such that when pressing the back button on device two that it navigates to fragment B?
Check out TaskStackBuilder or the activity XML declaration android:parentActivityName.
I solved this by just committing multiple fragment transactions. Works for me
supportFragmentManager.beginTransaction().replace(R.id.content, Fragment1(), "f1").addToBackStack(null).commit()
supportFragmentManager.beginTransaction().replace(R.id.content, Fragment2(), "f2").addToBackStack(null).commit()
supportFragmentManager.beginTransaction().replace(R.id.content, Fragment3(), "f3").addToBackStack(null).commit()
supportFragmentManager.beginTransaction().replace(R.id.content, Fragment4(), "f4").commit()
However, for a cleaner and better solution you could also have a look at the Jetpack Navigation UI
Related
I've been struggling with this problem for like a week, it's basically a Backstack problem I didn't found an optimal solution yet. I am working on a project which's flow is like this:
Activity (Fragment_A -> Fragment_B -> Fragment_C -> Fragment_A)
I am setting on Fragment_A one DatePicker and a TimePicker and I have 2 TextViews that redirect the user to Fragment_B. From Fragment_B I send some data to Fragment_C that converts the data and sends it back to Fragment_A.
The problem is that as far as I've understood is that when going back to Fragment_A it goes with a new instance, not the old, so my data there is lost. I resolved for now with sharedPreferences but it seems too complicated for a solution. I've tried with custom beginTransaction() and Navigation component but it didn't turn out well.
I was close, and when going from Fragment_C to Fragment_A there was the new instance on top of the old and at onBackPressed it popped the new instance, and showed me the old but how can I resolve so I won't need to press the back button? I tried to send a Boolean so if it's a new instance pop it, but it popped the old one I guess, because when I pressed back, it just quit the Activity instead of popping the new one.
Any help is appreciated!
An Activity-scoped ViewModel will make sharing data between child Fragments easier. Your Fragments observe the data in the ViewModel, so you don't even have to worry about passing data around. And with Navigation Component, you can use popUpTo and popUpToInclusive to pop Fragments B and C off the back stack, leaving just Fragment A.
If you're not familiar with these concepts, this free course covers them all wonderfully:
https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012
I am trying to return to a specific fragment after pressing the home button, sharing data with another app or switching activities.
Fragments in bottomNav:
A B C D
Fragments that are shared around the app and can be nested or navigated to from the bottomNav fragments:
E F G
Intended behaviour
User navigation stack:
A -> E
Presses home button and reopens app, stack remains the same.
A -> E
Actual Behaviour
User navigation stack:
A -> E
Presses home button and reopens app, brought back to first fragment
A
I tried to restore the navigation state by passing a bundle from navController.saveState() to a viewmodel during the Main Activity onPause method and restoring it with navController.restoreState() onResume to no avail. Is this not capable with the navigation component?
What you are looking for is called Multiple Backstack. Every Fragment in android maintains its own stack. So if you navigate to another Fragment in the ParentFragment, your ParentFragment will add the childFragment in its stack.
In your case, your ParentFragment is A and childFragment is E.
However, NavigationComponent has no vanilla support for Multiple Backstack. Ian Lake, the creator of NavigationComponent library is working on this issue since NavigationComponent was launched, and still haven't delivered on it. This doesn't mean he is not working on it, it simply means (as stated by Ian himself) that its harder to achieve because of Fragments API.
Coming back to your question, if you really want to implement MultipleBackstack then you can follow this project which pretty much anyone who wants MultipleBackstack with NavigationComponent first refers to. There is also a google sample that shows how to achieve this behavior.
I have one Activity with 3 fragments which form a workflow to collect user input.
Normally, Fragment A is the first fragment -> Launches B -> Launches C. B is supposed to launch A if the back button is pressed, and similarly C's Back button is supposed to launch B.
However, in some cases, A is supposed to launch C directly, and then C's back should launch A again.
I prefer that C should not know who launched it. I.e. I want C's "backstack" to operate without C knowing who launched it.
I tried using the usual addToBackstack approach, but I'm facing a problem when the Activity gets killed after the user lets the app go into the background while C was open.
I would like the user to return to "C" instead of starting all over from A. To achieve this I'm using the saved Instance state, and detecting which fragment was previously active, and launching it from the activity.
The problem starts when the user wants to go back from C, after the Activity was recreated after being killed. C doesn't know who launched it: A or B. How do I make the Back button work as expected for this case?
Found some answers in this excellent video by Android Developers + Adam Powell:
Fragments: Google I/O 2016
In summary, Fragments and the Fragment BackStack are considered part of the navigational state of the app, so, as long as I don't mess with the backstack when the activity is launched, the OS will also restore the FragmentBackStack, thus the BackStack will know who launched C (A or B) even if the activity gets re-created. Thus, popBackStack will move from C to A or B as required.
I have a Xamarin Android ActionBar-based app. I am not using anybody's compat library (Sherlock, etc.) I have a fragment for each tab. I have noticed the following behavior:
Suppose the user starts on Tab A, with corresponding fragment A. The user the switches to tab B, with corresponding fragment B. My code tells the app to detach fragment A, and attach fragment B. So far, so good. Now the weird part.
Suppose the user rotates the device. The fragments have all set
this.RetainInstance = true;
And I keep static references to them. So they stick around, which is what I want. But the weird thing is that when the activity is re-created after rotation, both fragments A and B get attached by Android, during my
base.OnCreate()
call from MyActivity.OnCreate(). This results in the app doing work which I assume is not needed. So my question is, how can I prevent that from happening?
You should read android guidelines. You must save the fragment state and the activity state and i suppose do not use static links and retainInstanceState. Google how to use Bundle and saveInstanceState, onCreate onRestoreInstancestate methods. Also after a recreation you can find you fragment by placed tag and reuse it without replace.
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
http://developer.android.com/guide/components/fragments.html
Let me explain my application first.
I have an activity and fragments in it. I'm opening fragmentA onCreate of application. In fragmentA,before i open fragmentB by using support fragment manager's replace() method, i call a webService for some json datas.
Then i open fragmentB with these json datas. After i opened the fragmentB, i want to turn back to fragmentA by using device's default backbutton, and i don't want to handle backButtonPress(). Just go back to previous fragment. My app does this.
Here is the question. When i press back button, my fragmentA calls the service again and it affects the user to wait. But how can i just turn to the previous fragment ?
I am looking for the best solution to turn previous fragment.