When to use FragmentManager::putFragment and getFragment
The basic answer:
These are only useful when implementing onSaveInstanceState() and restoring that state in onCreate(). If you are not implementing onSaveInstanceState(), you can forget about these methods and pretend like they don't exist.
The problem they are solving: if you want to save a reference to a fragment in your "saved instance state," you can't just put an object reference in there. First because well you can't put plain object in a Bundle. :) And the reason for this is that the point of that saved state is for it to be copied out of your process, so if your process needs to be killed, it can later be copied back in to a new process for you to re-initialize your activity/fragment from. A raw object is only meaningful in the context of the process it is running in, so it isn't possible to correctly copy the reference to such an object out of your current process and in to another.
So what putFragment()/getFragment() do is place a piece of data in the given Bundle that can identify that fragment across to a new instance of your activity/fragment in another process. Exactly what this representation is, is not defined, but in the current implementation it is the internal integer identifier for that fragment, which will be used later when the FragmentManager needs to re-create that fragment from a previously saved state... it is re-created with that same identifier, so when you then call getFragment() it can retrieve the integer, and use that to determine the correct Fragment object to return to the caller that corresponds to the one that was previously saved.
FragmentManager.put/getFragment vs findFragmentByTag
So what is the point of putFragment/getFragment?
According to the current implementation, what putFragment(Bundle bundle, String key, Fragment fragment)
do is put the index of a fragment into the bundle with the parameter key. And then getFragment(Bundle bundle, String key)
get the fragment at the same index which can be retrieved from the bundle with the same key. A Fragment has its index in the FragmentManager only after it is added to it, so putFragment() can be called on a Fragment only after it is added.
Does it save something extra or cause additional lifecycle stuff to
happen?
It save the index of a Fragment only, no more things else, nor do it cause any additional lifecycle stuff.
Is it just an alternative to findFragmentByTag() that does more or
less the same thing?
Yes, I thik so.
According to the current implementation, what putFragment/getFragment does can be achieved with findFragmentByTag()
too. But the function of putFragment/getFragment are quite limited because you can't use them without the bundle parameter, means you must call putFragment()
in onSaveInstanceState()
.
putFragment() - Fragment x is not currently in the FragmentManager
I've never used it myself, but have you looked at FragmentManager.executePendingTransactions()? Here's what the documentation says:
After a FragmentTransaction is committed with
FragmentTransaction.commit(), it is scheduled to be executed
asynchronously on the process's main thread. If you want to
immediately executing any such pending operations, you can call this
function (only from the main thread) to do so. Note that all callbacks
and other related behavior will be done from within this call, so be
careful about where this is called from.
It sounds like it matches your use case.
How to reconnect (Sherlock)FragmentActivity to retained fragment after orientation change
You can do something like this:
android.support.v4.app.Fragment fred = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getFragmentManager();
fred = (TaskFragment) fm.findFragmentByTag("fredFrag");
// if fred is null it means it is first time created activity
// so we add fragment to activity
// else fragment was added to activity and is
// retained across a configuration change.
if (fred == null) {
fred = new Fragment();
fm.beginTransaction().add(mTaskFragment, "fredFrag").commit();
}
}
Android save the user input in a several fragments
If what you want to save is the Fragment state as is, take a look at this other answer, which is more an explanation than an example. You should be using the putFragment
and getFragment
methods from your getSupportFragmentManager()
instance.
I recognize I've been a little late using these two bad boys on my own, but they're quite useful. Let me give you a hint on where to add them:
putFragment
Inside your Principal
activity, add this directly in your onSaveInstanceState
method. One call per fragment you want to save:
public void onSaveInstanceState(Bundle outState) {
Cliente fragment = getSupportFragmentManager().findFragmentById(R.id.myFragment);
getSupportFragmentManager().putFragment(outState, "cliente", fragment);
}
getFragment
You can (and should, actually) use getFragment
inside the onCreate
. Use the already passed savedInstanceState
variable, and slightly change the way you init the fragment:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
Fragment startFragment = null;
if(savedInstanceState == null) { // first open
startFragment = new Cliente( );
} else { // rotation, change where the fragment was already there
startFragment = fm.getFragment(savedInstanceState, "cliente");
}
transaction.add(R.id.myFragment,startFragment);
transaction.commit();
Related Topics
Margins of a Linearlayout, Programmatically with Dp
Onclick Method Not Working Properly After Nestedscrollview Scrolled
How to Bypass The Firebase Cache to Refresh Data (In Android App)
Help with a Custom View Attributes Inside a Android Library Project
Set Visibility of Progress Bar Gone on Completion of Image Loading Using Glide Library
Check for Access to Notifications Using Notificationlistenerservice
How to Use a Library Project in Android Studio
Specifying a Link Key in Android Without Pairing
View Pager + Imageview +Pinch Zoom + Rotation
Make Android Webview Not Store Cookies or Passwords
Gradle Project Sync Failing After Google Announced The New Sdk Versioning System
Reasons That The Passed Intent Would Be Null in Onstartcommand
Android - Set a Progressbar to Be a Vertical Bar Instead of Horizontal
How To: Install Plugin in Android Studio
Can't Create New Kotlin Project After Updating to Android Studio 4.2