With a firm understanding of layouts from Chapter 2, Layouts, we'll dig deeper into UI development with Fragments. Fragments are a way to separate your UI into smaller sections that can easily be reused. Think of Fragments as mini-activities, complete with their own classes, layouts, and life cycle. Instead of designing your screen in one Activity Layout, possibly duplicating functionality across multiple layouts, you can break the screen into smaller, logical sections and turn them into Fragments. Your Activity Layout can then reference one or multiple Fragments, as needed.
Android didn't always support Fragments. The early versions of Android were designed for phones when screens had relatively small displays. It wasn't until Android started being used on tablets that there was a need to split the screen into smaller sections. Android 3.0 introduced the Fragments
class and the Fragment Manager.
Along with a new class, also came the Fragment Lifecycle. The Fragment Lifecycle is similar to the Activity Lifecycle introduced in Chapter 1, Activities, as most events parallel the Activity Lifecycle.
Here's a brief overview of the main callbacks:
onAttach()
: It's called when the Fragment is associated with an Activity.onCreate()
: It's called when the Fragment is first created.onCreateView()
: It's called when the Fragment is about to be displayed for the first time.onActivityCreated()
: It's called when the associated Activity is created.onStart()
: It's called when the Fragment will become visible to the user.onResume()
: It's called just...Defining a Fragment in the layout, as we did in the previous recipe, is known as a static Fragment, which doesn't allow the fragment to be changed during runtime. Rather than using the <fragment>
element, we will create a container to hold the Fragment, then create the Fragment dynamically in the Activity's onCreate()
method.
The FragmentManager provides the APIs for adding, removing, and changing Fragments during runtime using a FragmentTransaction. A Fragment transaction consists of the following:
This recipe will demonstrate the Fragment Manager by adding and removing Fragments during runtime.
Create a new project in Android Studio and call it: RuntimeFragments
. Use the default Phone & Tablet
option and select Empty Activity
on the Add an Activity to Mobile
dialog.
Often, the need arises to pass information between Fragments. An email application serves as a classic example. It's common to have the list of emails in one Fragment and show the email details in another Fragment (this is commonly referred to as a Master/Detail pattern). Fragments make creating this pattern easier because we only have to code each Fragment once, then include them in different layouts. We can easily have a single Fragment in a portrait layout with the ability to swap out the master Fragment with the detail Fragment when an email is selected. We can also create a two-panel layout where both the list and detail Fragments are side by side. Either way, when the user clicks the email in the list, the email opens up in the detail panel. This is when we need to communicate between two Fragments.
Since one of the primary goals of Fragments is that they be completely self-contained, direct communication between Fragments is discouraged, and for good...
In several of the previous recipes, it was mentioned that you should call the addToBackStack()
method in the Fragment transaction to enable Android to maintain a Fragment back stack. This is the first step, but may not be enough to provide a rich user experience. In this recipe, we'll explore two other callbacks: onBackPressed()
and onBackStackChanged()
. As you'll see, by implementing these callbacks, your application can provide specific behavior for the Fragment back stack. The onBackPressed()
callback allows the app to check the back stack state and provide custom behavior, such as closing the app when appropriate.
The onBackStackChanged()
callback is called whenever the actual back stack changes - such as when a Fragment is popped from the back stack. By overriding this callback, your app can check the current Fragment and update the UI (such as the Home key back arrow) as appropriate.