How do Android Handle Fragment livecycle within a ViewPager? - android

This is not going to be a straightforward question. I'll explain myself as best as I can, so this might be a little bit long.
Explanation
Recently, I've been fighting a lot with Fragments and ViewPager.
What I found out, is that ViewPager, holds as many fragments as you want. When it's instantiated for first time, depending on the type ( FragmentStatePagerAdapter vs FragmentPagerAdapter Difference between FragmentPagerAdapter and FragmentStatePagerAdapter), it's going to create all Fragments or just the "needed" ones.
In those fragments, you're free to use methods like getActivity() which basically is the context used for creating Views, finding Views, displaying dialogs...
However, as soon as you leave the fragment, the getActivity() starts returning null, because the fragment is dettached from the Activity. Sounds logic.
But, what sounds illogical to me, hence im asking here, is that when you go back to the fragment page (or close enough), it's again triggering the base methods, like onAttach.
As soon as you've onAttach, you can keep the context provided by Activity, but if you try to do something like the following (pseudo-code):
class MyFragment extends Fragment
{
private Context context;
private doThingsAfterAttach()
{
getActivity(); //this is null.
null != context; //TRUE
}
#Override
public onAttach( Activity activity )
{
context = activity;
doThingsAfterAttach();
}
}
What you can see, is that getActivity() is returning null, even though you're calling this method after onAttach is triggered.
If you decide to cast the kept context to an Activity, to perform findViewById tasks, you will see that the view you're trying to find, is null, which means that couldn't be found / doesn't exist.
Issue
Imagine you have a ViewPager with 5 tabs (fragments).
When a task is performed on ANY of those 5 tabs, you want to notify the "holder" activity, in order to notify all fragments that should update it's content, as something has changed.
But when you notify them, if they have to change layout, they can't do it, because as soon as you try to findViewById, two things can happen: getActivity() is returning null, hence you can't get Views, and if you cast context to activity, it won't return any View when you search for any.
What scares me the most, is that when you rotate the device, acts like leaving the fragment page and going back; "loses" activity.
Real question
So what I'm looking for, is an answer which explains me what's happening internally, so I can find the appropriate code to handle those situations.
There's not much code I can provide, because it would be useless. Whoever uses ViewPager with Fragments, probably handled with those things, so you will understand me.
Thank you, and here I am ready to answer your questions.
Thanks.

note: This is a lengthy and probably boring post
Your problem with the ViewPager is not new. Don't feel bad. We've all went through what appeared to be a magic solution to a new paradigm (and I will put new in Italics because it wasn't necessarily new at the time). With the added support for Fragments (through the State and Stateless adapters that you mention) things quickly became more interesting.
I'm not going to go into the details whether the adapters are good or annoying (you can draw your own conclusions) or why the adapters (and the widget itself) lack very basic stuff that nobody understands what where the Android developers thinking when they exposed the public API for these.
Instead, I'm going to help you manage Activity/Fragment communication the way -I think- everybody does.
What is happening with Fragments in a ViewPager?
The Activity/Fragment concept is -in my humble opinion- horrible and it was a hack. But an effective one, since it quickly proved that it worked, to the point where the Android team decided to start adding Fragment support to more and more stuff. Even nested Fragments, yes Fragments inside Fragments! And since Android developers (less and less but still very often) have to deal with old versions of the platform, then all this support was initially added to the Support Library, and it never moved out of it.
But let's get back on topic. The Fragment lifecycle is somewhat confusing (in part thanks to the poor naming of some lifecycle methods and the order they are -not- guaranteed to occur). Some things are obscurely hidden behind unfriendly callbacks (TreeLayout anyone?).
So… the ViewPager needs an adapter. The adapter is in charge of supplying the ViewPager with its views. So while the ViewPager is a View that understands what a touch, drag, fling, draw, measure, etc. is, it really expects an Adapter to provide the data to display. (This is a huge simplification).
And here we have Two types of adapters which know how to deal with Fragments. One maintains a state and the other doesn't. Meaning one doesn't really release anything (FragmentPagerAdapter) and one does indeed release its fragments (FragmentStatePagerAdapter)… but wait… what is "release" in this context?
Turns out that Fragments don't really exist in a free world, they are dominated by a FragmentManager, who makes sure that they are not late and decides when to release them. This is a rule that not even the Adapters can override! So they must report to this FragmentManager anyway. You can tell that the adapter must talk to this FragmentManager because it must receive one in the Constructor!
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
Who is this FragmentManager anyway?
Well, the documentation is not very friendly, it just says:
Interface for interacting with Fragment objects inside of an Activity
Ok, thank you Mr. obvious!
In practice, the FragmentManager is a static class, you don't create it, you just get it from an Activity.
Now think of the FragmentManager of a controller who keeps a reference to your fragments, even long after you've left them. It knows how to bring them back, it helps them save their state when configuration changes (rotations, for example), it keeps a pile/stack of them, knowing in which order they can be popped back to life and it does all this, sporting FragmentTransactions that must be committed, much like a relational database transaction.
Most of this complexity (and I'm sure they had their reasons) happens behind the scenes, so you don't really have to worry too much about it.
Can we go back to the original question now?
Yes yes… it's a long subject as you can see, but let's get to the point, because I have to go back to work…
When the Fragment gets out of view, the adapter secretly tells the FragmentManager: "Yo dawg, this Fragment is no longer needed here -for now-". (It may not use that phrase but something like that). For a more detailed response, you can actually look at the more or less recent code of the FragmentStatePagerAdapter and learn a lot from it.
Look how it has a list of Fragments and SavedStates:
private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
and a reference to a FragmentManager:
private final FragmentManager mFragmentManager;
Not surprisingly, FragmentPagerAdapter doesn't have a list of Fragments nor a list of saved States, it simply lets the FragmentManager do its job.
So let's first look at the "State" pager adapter to see what's doing when it's time to Destroy a Fragment…
With Google's permission, let's look at the source code for destroyItem():
1 #Override
2 public void destroyItem(ViewGroup container, int position, Object object) {
3 Fragment fragment = (Fragment)object;
4 if (mCurTransaction == null) {
5 mCurTransaction = mFragmentManager.beginTransaction();
6 }
7 if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
8 + " v=" + ((Fragment)object).getView());
9 while (mSavedState.size() <= position) {
10 mSavedState.add(null);
11 }
12 mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
13 mFragments.set(position, null);
14 mCurTransaction.remove(fragment);
15 }
Line 4 starts a FragmentTransaction if one hasn't already been started.
Lines 9-11 pads out the mSavedState array with null entries until it’s at least the size of the index of the fragment we’re removing.
Line 12 saves the state of the Fragment being removed (so it can be restored in the future if needed).
Line 13 is effectively removing the Fragment reference…
Line 14 adds this to the Fragment's Manager transaction so the FragmentManager knows what to do.
(Note: there's an obscure bug in the ViewPager when you add/change/remove Fragments dynamically, I'll link to the problem/solution at the end).
When you add a Fragment to the ViewPager, the process is relatively similar (see instantiateItem() method…
It first checks if the object is already instantiated, then it returns it immediately.
If the Fragment is not there, one is created…
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
Fragment fragment = getItem(position);
Remember you extend this Adapter and create your own getItem() method, this is where it gets called. You are giving the Adapter a newly created Fragment.
Next the Adapter checks for the savedState of the fragment to see if it can find one (and here it makes a mistake) (see link at the end)…
Finally it proceeds to add the newly received Fragment:
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
mCurTransaction.add(container.getId(), fragment);
It must add null padding for the array to be the exact size, and also uses the FragmentTransaction of course.
The moral of the story so far is that the Adapter keeps its own collection of stuff but it keeps the boss (a.k.a.: FragmentManager) happy by letting him know he's in control.
For reference, the support v13 versions are pretty much the same, but have references to the non support version of Fragment, FragmentManager, FragmentTransaction, etc.
So if the Adapters either keep a list and ask the FragmentManager (through a FragmentTransaction) or just use the FragmentManager, what does the FragmentManger do?!
This is lot more "complicated" but the FragmentManager implementation has a list of Added and Active fragments (along with a myriad of other collections and data structures).
ArrayList<Fragment> mActive;
ArrayList<Fragment> mAdded;
^ That's coming from the FragmentManagerImpl class!
So I won't go into details about the FragmentManager (you can find its source code here), because it's a really big class and it uses transactions for everything and it's super messy. It keeps a state machine about each fragment (created, initializing, etc.). The interesting method is perhaps moveToState() and this is where the Fragment lifecycle callbacks are made, so take a look at the source code to see what's going on.
Also take a look at the removeFragment() method there, which ends up calling the moveToState() method in the end.
Enough with all this… when can I call getActivity() and not get null in my Fragments?
Ok, so you provided an example of what you wanted to do.
You have ViewPager with 5 Fragments (for example) and you want to notify them that something has happened so they can do something about it. A lot of somethings.
I'd say that this is a typical Observer pattern + ViewPager.OnPageChangeListener().
The observer pattern is simple, you create an Interface like:
public interface FragmentInterface {
void onBecameVisible();
}
Your Fragments implement this interface…
public Fragment YourFragment implements FragmentInterface {
and then you have a:
#Override
public void onBecameVisible() {
if (getActivity() != null && !getActivity().isFinishing()) {
// do something with your Activity -which should also implement an interface!-
}
}
And who calls onBecameVisible?
Your ViewPager.OnPageChangeListener() in your Activity:
public void onPageSelected(final int i) {
FragmentInterface fragment = (FragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
if (fragment != null) {
fragment.onBecameVisible();
}
}
So now the Activity can reliably tell the Fragment that it has become visible.
Now… if you want to tell the OTHER Fragments, then you have to have a list of "listeners" (Observer pattern) but you must understand that according to what we've seen about the Adapters and the Fragment Manager, Fragments may be detached (even tho they may not necessarily be destroyed). The fact that they are not visible, could mean they are prone to have their view hierarchy destroyed (so changing it at that point would not be possible).
Your best bet is to make sure your onCreateView is capable of asking which view should be displayed based upon your business logic.
The best way to understand the lifecycle is to add a Log to EACH of the Fragment lifecycle (onStart, Stop, Pause, Resume, Detach, Destroy, ActivityCreated, etc…) and see how they react when you move through the ViewPager.
I hope this lengthy post gives you an idea about what's the ViewPager doing with your Fragments. Let us know if you have more specific questions or if I haven't really helped you :)
Regarding the BUG I mentioned earlier, take a look at this post which talks about a bug in (and a fix for) the way FragmentStatePagerAdapter handles fragment restoration.

I think getActivity() return null onAttach() because you haven't called it's super in other words it didn't get the chance to set it as its activity . Also you don't need to call getActivity() to find views, you can keep their references on onCreateView() and update them on onStart() if there should be any change in their values.
Also keeping the activity context as global will prevent the fragment from being garbage collected as long as activity lives. So release the reference on onDetach().

If your problem is that you want to notify the Activity, simply pass the Activity as "listener" to the fragment. Remember to pass it as WeakReg tough to try to avoid leak issues.

Related

Android - Communicating between Fragments

I'm trying to access a function in one Fragment (f1) from another Fragment (f2). It seems that i have to make my function in f1 public and static to be able to access it from f2.
I've read that it's not a good idea to access one Fragment from another, so i've tried to make f2 access my Activity, which then connects to the function in f1. Although, even doing it this way, i still have to make my function in f1 public and static.
I don't reuse the Fragments, i simply have them in a ViewPager for swiping back and forth through the Fragments.
At the moment i have a lot of static variables because i have to make my functions static to access them from other Fragments.
Am i going about this the wrong way? Is there a better way?
Thanks in advance.
You're going down a road of much pain unless you are very controlled about what you do.
First of all, sharing state through static methods and variables is a fairly awful way of doing things, and static members won't be able to access anything in the instance of the fragment. If you really think you need to use static methods, don't bother putting them in the fragment classes. They don't provide an advantage there. Put them in a common class that they all reference.
Second of all, if you're using a ViewPager with fragments, you can't be guaranteed that any given fragment's view hierarchy even exists at any moment in time. This is because ViewPager typically only keeps fragment views alive that are on the current page or on +/- 1 offset from the visible page. So if you need to tell a fragment at offset +2 from the current fragment, you won't be able to make visible changes to it.
Instead, the easiest thing to do is create an object that maintains whatever state you want to share between the fragments, and have them all make changes to that one object. If you need instant changes to other fragments, you can use something like an event bus to have those changes communicated to other active fragments.
What you're trying to do is in general fairly complex. Expect to spend a lot of time designing a correct solution, and be sure to learn how fragments and ViewPager works very well.
You got two questions
1. Am i going about this the wrong way?
Yes, its not recommended to have the methods & variables declared static just to make them used to access from outside of your class.
2. Is there a better way?
Yes, declare the methods as public (but not static) inside its fragments.
From the activity (which is hosting the fragments) get the reference to the fragments using FragmentManager classes methods findFragmentById() or findFragmentByTag() then call the methods.
Sample :
Fragment fragment =
fragmentManager.findFragmentByTag.findFragmentById
(R.id.fragment);
or
Fragment currentFragment =
fragmentManager.findFragmentByTag("fragmentTag");
If you really require both of your functions to be isolated, you can use Broadcasts. Just send a Broadcast from one fragment and have the Broadcast receiver in the other fragment.

putFragment of FragmentManager generates same integer for all fragments

I tried to use putFragment to save reference for fragments for using it in future (and not recreate) before replace.
BaseFragment last = (BaseFragment) mContext.getSupportFragmentManager().getFragments().get(mContext.getSupportFragmentManager().getFragments().size() - 1);
mContext.getSupportFragmentManager().putFragment(mContext.getBundle(), last.getType().toString(), last);
And before creating new fragment i check bundle for fragment existing:
BaseFragment f = (BaseFragment) getSupportFragmentManager().getFragment( mBundle, type.toString());
if(f != null)
return f;
else
// create new fragment
FragmentType is just my enum:
public static enum FragmentType{
PROJECTS,
BALANCE
}
But for all fragments (for all keys in bundle) it generates same integer value.
So getFragment method returns wrong fragment. Where is the problem?
I saw this post with same issue. But it still is not resolved...
I needed it for storing fragment state while replacing it. I tried it after this answer.
Use cases of these methods are described in this question: get/putFragment()
Also, don't use getFragments(); It is a method annotated by #Hide and is not supposed to be used, because android can destroy an recreate activities and fragments at any given time, so the list is not always correct.
While the methods do give acces to the 'pointer' of the fragment, It is meant to only restore state.
Java is a language with a garbage collector, and android builds on top of that with objects that do not give us control over their lifecycle.
These methods (put, get) are meant to be used inside onSaveInatanceState and onRestoreInstanceState to save the "state" of the fragment so that it (the state) can be restored later.
Are you using them in that context?
If not, you are essentially trying to override the way the OS handles the fragments' lifecycle, which is asking for trouble.
In other words, don't try to get back the same instance, the system just cannot guarantee that to you.
There is an interesting discussion on this issue over at the android developers

ViewPager Fragments getting destroyed while app is in background?

I can't for the life of me figure out why sometimes my Fragments become uncontrollable after my app has been launched, paused, and then resumed.
I hold references to my Fragments like this:
public class MainActivity ... {
public static AccountFragment accountFragment;
....
#Override
protected void onCreate( ... {
accountFragment = new AccountFragment(this);
...
}
I have a custom toolbar with a Spinner which theoretically should allow the user to cause an AsyncTask in the AccountFragment to run. This is implemented like so:
if (accountFragment.getView() != null) {
accountFragment.load()
}
I then create a ViewPager, a FragmentPagerAdapter, etc.
This works completely fine most of the time. The user can select a new item in the Spinner and the AccountFragment will update accordingly. However, sometimes after the app has been stopped and then later resumed, the AccountFragment will not respond at all to anything. Even other views in the app which should affect the AccountFragment are useless. It makes no sense to me because the AccountFragment's view cannot be null, and the AsyncTask which is executed by accountFragment.load() makes some very simple changes to the UI in its onPreExecute which should be very apparent (e.g. Everything disappears and a ProgressBar appears) which is simply not happening.
Any ideas?
There's not enough code to know exactly what's going wrong here, but there are also a bunch of stuff you're doing wrong.
1) Don't store fragment reference in a public static field. Make it just private, or protected at most. Read basic Java manuals for explanation.
2) Don't overload Fragment's constructor, it's discouraged by design. If you need to pass some values to it, do it by using arguments.
3) I guess you're not performing a check during onCreate() method in your Activity if it's being recreated or freshly created. You could end up with two instances of AccountFragment where one of them is in some weird detached state.
...
You should probably spend more time researching basics about Fragment/Activity relationship and how to avoid situations like this.
What you need is override these methods:
onSaveInstanceState(){}
onCreate (Bundle savedInstanceState){}
or onCreateView()
See http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle) . You put all the necessary parameters to bundle in onSaveInstanceState() and restore them in onCreate() or onCreateView().

Android, why shouldn't one Fragment call another directly?

According to Android guidline, http://developer.android.com/training/basics/fragments/communicating.html
One fragment should send data to another one via the hosting Activity. I'm wondering there is a reason for that.
Since in my code, I put one variable to hold pointer to the another fragment, and assign it in onActivityCreated
//this code is in class FragmentType1, assign the pointer to the FragmentType2 for later use
#Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final FragmentManager fm = getFragmentManager();
mOtherFragment = (FragmentType2) fm
.findFragmentById(R.id.container_fragment);
}
and later if I want to set data for FragmentType2, I just call:
public setData(MyData data){
if (mOtherFragment!=null)
mOtherFragment.setData(data);
}
Everything is working fine now. What's wrong with that approach? Tks.
There's at least 2 reasons for it:
To facilitate de-coupling of fragments.
To avoid memory leaks that can happen by storing a reference to one fragment in another.
Another reason would be to maintain the state when the hosting activity is destroyed.
After recreation, you could fetch the state from the hosting activity, since the fragment itself would be unable to save it's state directly.
And last but not least, it is really hard for dynamically added fragments, especially when it comes to nested fragments, to get sure that both fragments are "alive" at the same time. Fragments life cycle is complex to manage properly and using a direct communication presumes you completely control this, which is rarely true.
The best model to my mind is to use an event bus, like Otto or EventBus or RoboGuice's bus.

Android - Memory pressure crashes with ViewPager > Fragments > Activities

I am using the v4 Support library in our app, and I have a step-based process in the app that is working fine under normal circumstances. However, we have a requirement that everything needs to work and not crash under memory pressure situations. So I'm using the SetAlwaysFinish library to help with this (https://github.com/bricolsoftconsulting/SetAlwaysFinish). It's been extremely helpful in pinpointing areas the need to detect and handle these kinds of situations, but I've run into one that has me stumped. Keep in mind this works fine under normal circumstances, but I'm explicitly testing with the "setAlwaysFinish" = ON.
Here's my setup: I have a "ProcessActivity" class that hosts the layout for a ViewPager. The ViewPager has an Adapter set, which contains my list of Fragments that will encompass the process. This is in the onCreate() method:
ProcessActivity:
createSteps(); // this creates/populates the ArrayList "processSteps" with Fragments
theAdapter = new ProcessAdapter(this, processSteps); // the ProcessAdapter class extends FragmentStatePagerAdapter, with an additional list of Fragment steps
theViewPager.setAdapter(theAdapter);
There are other pieces, but that is the core of how it's setup. During one of the Fragment steps, I actually need to "break" from the step process and push out to an Activity temporarily to do some logic (and then subsequently return to the step process). I do this as follows, with a ForResult, since I need to be able to handle an OK/Cancel action in the activity when it finishes:
Step4Fragment:
Intent intent = new Intent(getActivity(), ThePushActivity.class);
intent.putExtra(blah..);
startActivityForResult(intent, THE_REQCODE);
Once it pushed onto this view, sometimes the onDestroy() method of both the ProcessActivity and Step4Fragment are called (due to the alwaysFinish). Sometimes it seems to work fine and it calls back into the Step-Fragment process. But usually, what it does is that it will call the ProcessActivity's onDestroy() method, and then it will re-call the onCreate() method with the bundle saved-instance-state populated. This will call the step-creation code above, and it puts the app in a funky state where the last step the user was on is showing, but behind the scenes it's actually on the first step (fragments are, at that point, out of whack and disconnected), and a crash inevitably occurs. It seems at this point, the Step4Fragment is completely disjointed and will crash somewhere if you try to do anything, even though it seems as if it got re-instantiated correctly
Any thoughts on best ways to address this? I think it's fine if I find a way to even just reset things so that it kicks the user back to the first step of the process if a memory issue is occurring. However, my whole concern is the crash, of course.
Let me know if I need to provide more specifics. Thanks in advance for any help!
UPDATE #1:
Just a quick update that I've noticed that the Fragments are re-instantiated and initialized, and it properly falls into the "current" Fragment's onActivityResult() method and does what it needs to do properly. It seems where the disconnect lies is in the base ProcessActivity class, following one of these scenarios. The ViewPager layout shows properly, but everything outside of the ViewPager is not correct (i.e. it is indicating that it's on the 1st step of the process, when it should indicate that it's on the 4th, and the navigation buttons are showing for the 1st step rather than the 4th).
So I'm guessing I need to somehow properly set those elements manually. In digging deeper into this, I may be leaving out pieces of code that are needed for someone to actively help with this. If I could somehow access the state of a ViewPager field, which contains the ability to get the "currently shown fragment", before this whole onDestroy()/onCreate() was called, possibly from the savedInstanceState bundle? That would probably solve my issue. But from inspecting this bundle upon debugging, I pretty much only see the Fragments themselves, and their respective states. I'll keep digging, though.
Regardless, please let me know if anyone has any ideas on how this kind of thing should properly be done (at a high level, of course).
UPDATE #2
I'm seeing that even tho the "current" Fragment seems to be initiated correctly, and the view shows correctly, everything is detached. I can't call any methods on getResources() or getActivity(), etc. I actually was able to get the ProcessActivity 'working' properly based on saving off the step index (int) into the savedInstanceState bundle, and then reloading the UI elements around it. However, I still have this blocker with the current Fragment being detached from the Activity, even though it's seemingly re-instantiated properly.
UPDATE #3
When I follow the direction of this post: ViewPager and fragments — what's the right way to store fragment's state?, I end up with an immediate exception when I try to do the first putFragment(). The exception is: "IllegalStateException: Fragment Step4Fragment is not currently in the FragmentManager". I'm thinking this may have to do with the fact that I'm only keeping one Fragment to the left and one fragment to the right 'active' at any one time (i.e. offScreenPageLimit).
Are you sure that your Fragment isn't being re-instantiated?
All subclasses of Fragment must include a public empty constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it. If the empty constructor is not available, a runtime exception will occur in some cases during state restore.
Turns out that the solution to this was similar to the solution presented in this post: ViewPager and fragments — what's the right way to store fragment's state?
I had a couple things going on that needed to change. First off, I needed to move the Fragments to fields rather than temp variables. Secondly, I needed to avoid instantiating new Fragments each time in the onCreate(). Instead, it should try to pull them from the savedInstanceState as such:
fragment1 = (Fragment1Step) getSupportFragmentManager().getFragment(savedInstanceState, Fragment1Step.class.getName());
fragment2 = (Fragment2Step) getSupportFragmentManager().getFragment(savedInstanceState, Fragment2Step.class.getName());
etc...
and then right after this, I have subsequent checks for each of them; if they are null (i.e. coming in fresh and not from a saved instance), then they will be instantiated new:
if (fragment1 == null) {
fragment1 = new Fragment1Step();
}
if (fragment2 == null) {
fragment2 = new Fragment2Step();
}
In order for this to work, of course, these should also be saved off in the onSaveInstanceState() method:
try {
getSupportFragmentManager().putFragment(outState, Fragment1Step.class.getName(), fragment1);
} catch (Exception e) {
// do nothing
}
try {
getSupportFragmentManager().putFragment(outState, Fragment2Step.class.getName(), fragment2);
} catch (Exception e) {
// do nothing
}
etc...
The reason why I have these in try/catch blocks is because our ViewPager only has an offScreenPageLimit of 1, so some of these will throw exceptions upon the "putFragment()" call if they are not currently in the 'active' stack of Fragments being shown.
It's not extremely pretty, and there may be a better way to handle this.. but this seems to work fine with this now in place.

Categories

Resources