Managing Fragments
To help with managing Fragments, Android provides the FragmentManager
class. Each Activity has an instance of Android.App.FragmentManager
that will find or dynamically change its Fragments. Each set of these
changes is known as a transaction, and is performed by using one of
the APIs contained in the class Android.App.FragmentTransation
, which
is managed by the FragmentManager
. An Activity may start a
transaction like this:
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
These changes to the Fragments are performed in the
FragmentTransaction
instance by using methods such as Add()
,
Remove(),
and Replace().
The changes are then applied by using
Commit()
. The changes in a transaction are not performed immediately.
Instead, they are scheduled to run on the Activity's UI thread as
soon as possible.
The following example shows how to add a Fragment to an existing container:
// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
DetailsFragment aDifferentDetailsFrag = new DetailsFragment();
// The fragment will have the ID of Resource.Id.fragment_container.
fragmentTx.Add(Resource.Id.fragment_container, aDifferentDetailsFrag);
// Commit the transaction.
fragmentTx.Commit();
If a transaction is committed after Activity.OnSaveInstanceState()
is
called, an exception will be thrown. This happens because when the
Activity saves its state, Android also saves the state of any hosted
Fragments. If any Fragment transactions are committed after this point,
the state of these transactions will be lost when the Activity is
restored.
It's possible to save the Fragment transactions to the Activity's
back stack
by making a call to FragmentTransaction.AddToBackStack()
. This allows
the user to navigate backwards through Fragment changes when the
Back button is pressed. Without a call to this method, Fragments
that are removed will be destroyed and will be unavailable if the user
navigates back through the Activity.
The following example shows how to use the AddToBackStack
method of a
FragmentTransaction
to replace one Fragment, while preserving the
state of the first Fragment on the back stack:
// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
DetailsFragment aDifferentDetailsFrag = new DetailsFragment();
// Replace the fragment that is in the View fragment_container (if applicable).
fragmentTx.Replace(Resource.Id.fragment_container, aDifferentDetailsFrag);
// Add the transaction to the back stack.
fragmentTx.AddToBackStack(null);
// Commit the transaction.
fragmentTx.Commit();
Communicating with Fragments
The FragmentManager knows about all of the Fragments that are attached to an Activity and provides two methods to help find these Fragments:
FindFragmentById – This method will find a Fragment by using the ID that was specified in the layout file or the container ID when the Fragment was added as part of a transaction.
FindFragmentByTag – This method is used to find a Fragment that has a tag that was provided in the layout file or that was added in a transaction.
Both Fragments and Activities reference the FragmentManager
, so the
same techniques are used to communicate back and forth between them. An
application may find a reference Fragment by using one of these two
methods, cast that reference to the appropriate type, and then directly
call methods on the Fragment. The following snippet provides an
example:
It is also possible for the Activity to use the FragmentManager
to
find Fragments:
var emailList = FragmentManager.FindFragmentById<EmailListFragment>(Resource.Id.email_list_fragment);
emailList.SomeCustomMethod(parameter1, parameter2);
Communicating with the Activity
It is possible for a Fragment to use the Fragment.Activity
property
to reference its host. By casting the Activity to a more specific type,
it is possible for an Activity to call methods and properties on its
host, as shown in the following example:
var myActivity = (MyActivity) this.Activity;
myActivity.SomeCustomMethod();