How to retain state of a fragment while switching between different fragments - android

I have an activity consisting of 3 fragments and a bottom navigation view which navigates the user to different fragments.
Let say the fragments are A, B and C.
The issue I am facing is that if I have performed some operation in A, and I navigate to B, then, when I again navigate to A (from bottom navigation view and NOT backpress) , the operations performed on A are lost, which I don't want.
For eg, in Youtube application, after searching something on Home fragment, if I navigate to "Subscriptions" or "Library", then if I renavigate to "Home", the search results are retained and also the state of the screen.
Kindly guide me how to achieve the same in my application

Related

How to navigate to a fragment present in backstack in Android Studio?

Suppose I have different fragments within an activity in backstack such as [1]->[2]->[3]->[4]->[5] with Fragment 5 presently visible on the screen. Now I want to go to Fragment 2 without destroying Fragments 3 and 4 on a single press of a button. How can this be done?

Clear backstack and replace current fragment with a top-level fragment

I have one activity in my android app which handles the replacement of multiple views/fragments. This activity also has a navigation drawer to navigate to top-level fragments. From the top-level fragments you can navigate to detail-level fragments.
The navigation drawer can always be accessed by sliding it in from the left side. If the current fragment is a top-level fragment, the navigation-drawer can also be accessed by the action-bar. If the current fragment is a detail-level fragment, you can navigate back through the action-bar (or by pressing the back-button).
Lets say I have 3 top-level fragments which can be accessed through the navigation drawer.
fragment[1], fragment[2], fragment[3]
From fragment[1], you can navigate to the detail-level fragment[1.1].
Now the user wants to navigate directly to the top-level fragment[3] from the current fragment[1.1]. The user just has to slide in the navigation-drawer and click the item for fragment[3].
Now, if the user hits the back button, the application should close (because it navigated to a top-level fragment). So every time the user navigates to a top-level fragment, the backstack should be cleared. To check if I should display the drawer indicator, I am reading the getBackStackEntryCount()-value and compare it with 0.
As a summary. I want to navigate from detail-level fragments to any top-level fragments and clear the backstack.
The problem:
When I clear the backstack by executing
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);,
the fragment transactions are replayed in reverse (for example the replacement of fragment[1] by fragment[1.1]). And I DON'T want them to be replayed. I have a lot of initializations in onCreateView, onViewCreated, onStart, .., also starting tasks to fetch data. And I want to skip that all. Just replace the detail level view with a new top-level one which wasn't already in the backstack.
I couldn't find any solution to clear the backstack without popping transactions.
Is there a clean solution to handle this problem? Do I have to implement my own backstack-behavior?
EDIT:
The YouTube app also behaves like this. When you navigate from detail to top-level, the backstack gets cleared. But how do they clear the backstack without replaying the fragment-transactions?
Thanks for your answers.
I think you problem is that you are popping fragments in a loop - I guess. I usually push fragments on the fragment stack together with specifying custom animations - say slide in new fragment from the right and when popping it our slid out to the right. Now - if your user has navigated to fragment 1 then 1.1 then 1.2 etc and you want to navigate back to 1 when a user clicks the home button in the action bar - specify a name for you fragment 1 transaction. The you you perform popping use that name. Also consider using popBackStack function instead of popBackStackImmediate.

Android Navigation Drawer with many fragments

I've been struggling with this for a while now, I want to start off with a diagram of my problem:
The three navigation drawer buttons are part of my Base Activity. Each purple block below the three buttons are fragments, and the descendants of each of those blocks are in turn fragments. I'll use the master and detail fragments as a demonstration of the issue I am having...The user clicks the nav drawer button, which opens the master fragment that hosts a list of articles. Once a user clicks one of those articles, I then open the detail fragment inside of the master fragment. So If I find myself at the detail, and I decide to open the nav drawer and click the third button for instance, then click the second button again, I want the detail to be open still, and if I hit the phone's back button I want it to move back to the master fragment, and end there. Any tips will be helpful, as I am probably going to use a similar pattern for the first button, it's main fragment and it's children fragments as well.
In my opinion, the cleanest way to handle what you are describing would be to have three separate FragmentActivity classes that implement the DrawerLayout instead of one monolithic BaseActivity.
Each button in the drawer should start it's respective FragmentActivity using launchMode singleTask. This ensures that you launch the same activity instance each time, instead of a new one, which will maintain your back stack for each activity as you switch between them using the drawer buttons. See Android Developer Guide Activity:launchMode for more details.
Each of the three FragmentActivity instances should be responsible for starting and managing it's fragments using listener interfaces. For example, where you have your Master fragment opening a Detail fragment directly, you should instead have your Master fragment tell it's FragmentActivity that it needs to open the Detail fragment. See Android Developer Guide: Communicating with Other Fragments for recommended practices in implementing this type of decoupled communication between FragmentActivity and Fragment. It will make your life much easier down the road when you want different layouts for tablets, etc.
Each of the three main drawer "tasks" seem to be unique enough that isolating each within it's own FragmentActivity seems the best way to implement what you are trying to do. You can apply this same approach for each of your main sections.
I had the same problem and didn't want to go to multiple activities since that would complicate the back navigation of my application. Your fragments won't save their state automatically unless the activity lifecycle events are being called.
In our case those don't happen since we're not leaving the activity. You can use FragmentManager's saveFragmentState on the fragment you are replacing to manually trigger the state saving and get a Fragment.SavedState object. You can keep a list of your SavedState objects and when pushing a fragment check if you have a saved state for it. If so you can call Fragment setInitialSavedState which will cause your fragment to load the previous state.
Now in my app as a user toggles between fragments with their own child fragments the state is retained when they come back.

Using Fragments instad of separated activities

im going to write a little android app. Nothing complicated, with 6 "screens". 4 of them are on the same view navigation hierarchy level. 2 are subscreens of one of those 4.
For example screen A displays a list with information. By clicking on a list item the app will show screen A1. Screen A1 displays details about the previously selected list item. So Screen A1 is a subscreen of screen A. By clicking on the back button the app shows screen A.
Screen B has also a subscreen, called B1. The other screens are C and D which are on the same view navigation hierarchy as A and B (but not A1 and B1). So A, B, C, and D are on the top of the view navigation hierarchy. The App will start with displaying screen A. In the action bar (or in a sliding menu) you will find buttons to jump to screen B, C and D.
I hope you got an idea of what im trying to do. So normally I would say, every screen is a own activity. Im a big fan of fragments and i normally use them everywhere. In fact I caught myself implementing activities that contains only one fragment, that contains the main view layout. And I can say there is absolutely nothing wrong to do so (Fragments bring big advantages ... )
But now I wonder if it would be a good idea to use a single main activity and change only the fragments in this activity. So screen A, B, C, D, A1, B1 are Fragments instead of activities. So by navigating from Screen A to C I would simply replace fragment A with fragment C in the main activity (instead of starting a new Activity that contains the fragment C). The same way I would implement a navigation from screen A to subscreen A1.
So far I can't see nothing wrong with this approach. In my opinion it would be something like a ViewPager, just without swipe gestures to navigate between screens.
The only thing Im not sure about it (and thats my question) is the memory management. Whenever I do a replace fragment transaction (fragment manager) to navigate from screen A to B the fragment A should be destroyed and the memory should be garbage collected (somewhere in the future), right? When do I instantiate Fragment B? When the user clicks on the button to navigate to B (and repalce A)? Could this bring performance issues (time to instantiate the fragment)?
What if I set all fragments A, B, C, D, A1 and B1 to setRetainInstanceState(true)? Than the class member fields of each screen will be hold in the memory until the MainActivity is finished right?
Does anyone of you have experience with that?
A ViewPage uses some kind of "preloading" fragments and loads only the view layout of the next and previous fragment (setOffscreenPageLimit() )
Do you guys think I have to do something similar to avoid memory and performace issues?

Android SDK Fragments -- retain State over multiple activities

I am developing an application where i have a main activity consisting on the left of a fragment showing products. Depending on the selection, the right part of the landscape-view shows detailed information, where the product's properties can be thoroughly specified. This is the case if the application's running in landscape-mode. If the orientation changes to portrait-mode, then the user first selects a product and then specifies the product's properties by individual dedicated activities, where each activity contains exactly one fragment of the previously mentioned landscape-view.
The problem now comes when I rotate my screen during runtime. Assume that I started the application in portrait mode, and I select the first product (Activity A, Fragment A). The next screen (separate Activity, call it Activity B) will contain a Fragment B where I can specify Property 1 of the product. Now I rotate the screen. The application will then show the landscape-view where the first product is selected, and ALL fragments dedicated to product configuration are shown at the right. Is there a solution that I can retain the configurations done by the user in the separate activity (i.e. Fragment B, Activity B) in such a manner that the land-scape view receives the state such that the details view can properly show the hitherto done configurations?
To summarize:
I am in Activity A, just containing a list of products (Fragment A)
I select the first
then I get to a new Activity B, where Fragment B is shown
then I rotate my screen
then I get back to Activity A, now containing at the left side Fragment A (the list) and at the right side (among others) Fragment B.
I want the state of Fragment B in Activity B be available in Activity A, Fragment B.
Hope I could completely specify my question.
TIA
Gerald
There are 2 solutions that I could think of right now:
Forget about 2 Activities in this case, and solve this scenario with only 1. I had multiple projects with exactly these requirements. In portrait mode, I used a ViewSwitcher or a ViewFlipper to show Fragment A or Fragment B full-screen. On landscape, things remain the same you described. This way the 2 fragments can communicate with each other, Fragment B may update the selection on Fragment A.
Start Activity B with .startActivityForResult(), so it may supply a result for Activity A, containing the current selection.

Categories

Resources