Performing Fragment Transactions
A great feature about using fragments in your activity is the ability to add, remove, replace, and perform other actions with them, in response to user interaction. Each set of changes that you commit to the activity is called a transaction and you can perform one using APIs in FragmentTransaction. You can also save each transaction to a back stack managed by the activity, allowing the user to navigate backward through the fragment changes(similar to navigating backward through activities).
You can acquire instance of FragmentTransaction from the FragmentManager like this:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Each transaction is a set of changes that you want to perform at the same time. You can set up all the changes you want to perform for gaving transaction using methods such as add(), remove(), and replace(). Then, to apply the transaction to the activity, you must call commit().
Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.
For example, here's how you can replace one fragment with another, and preserve the previous state in the back stack:
//create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager.beginTransaction();
//Replace whatever is in the fragment_container view with this fragment, and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
//commit the transaction
transaction.commit();
In this example, newFragment replaces whatever fragment(if any) is currently in the layout container identified by the R.id.fragment_container ID. By calling addToBackStack(), the replace transaction is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the Back button.
If you add mutiple changes to the transaction (such as another add() or remove()) and call addToBackStack(), then all changes applied before you call commit() are added to the back stack as a single transaction and the Back button will reverse them all together.
The order in which you add changes to a FragmentTransaction doesn't matter:
1.You must call commit() last;
2.If you are adding mutiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy.
If you do not call addToBackStack() when you perform a transaction that removes a fragment, then that fragment is destroyed when the transaction is commited and the user cannot navigate back to it. Whereas, if you do call addToBackStack() when removing a fragment, then the fragment is stopped and will be resumed if the user navigates back.
Calling commit() does not perform the transaction immediately. Rather, it schedules it to run on the activity's UI thread(the "main" thread) as soon as the thread is able to do so. If necessary, however, you may call executePendingTransactions() from your UI thread to immediately execute transactions submitted by commit(). Doing so is usually not necessary unless the transaction is dependency for jobs in other threads.
You can commit a transaction using commit() only prior to the activity saving its state(when the user leaves the activity). If you attempt to commit after that point, an exception will be thrown. This is because the state after the commit can be lost if the activity needs to be restored. For situations in which its okay that you lose the commit, use commitAllowingStateLoss().
Communiating with the Activity
Although a fragment is implemented as an object that's independent from an activity and can be used inside mutiple activities, a given instance of a fragment is directly tied to the activity that contains it.
Specifically, the fragment can access the Activity instance with getActivity() and easily perform tasks such as find a view in the activity layout:
View listView = getActivity().findViewById(R.id.list);
Likewise, your activity can call methods in the fragment by acquiring to the Fragment from FragmentManager, using findFragmentById() or findFragmentByTag(). For example:
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
Creating event callbacks to the activity
In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.
For example, if a news application has two fragments in an activity--one to show a list of articles(fragment A) and another to display an article(fragment B)--then fragment A must tell the activity when a list item is selected so that it can tell fragment B to display the article. In this case, the OnArticleSelectedListener interface is declared inside fragment A:
public static class FragmentA extends ListFragment {
...
//Container Activity must implement this interface
public interface OnArticleSelectedListener {
}
}