Sunday, November 24, 2013

Android Fragment Summary I

Activities are not built to provide UI flexibility. An activity is tightly coupled with its view. The view that the activity inflates in the call to SetContentView(...) is tied to the activity until death do them part. We cannot swap out an activity's entire view (without destroying the activity) or pass a view from one activity to another at runtime.

Fragments were introduced in API level 11, so we have to find a way to ensure its compatibility with older versions of Android. The support library provides  fragment-related class (android.support.v4.app.Fragment). Also for lower API levels, we use FragmentActivity, which is an Activity subclass that provides the fragment-managing capabilities of the newer Activity class.

To host a UI fragment, an activity must

  • define a spot in its layout for the fragment's view.
  • manage the lifecycle of the fragment instance.

Since a fragment works on behalf of an activity, its state should reflect the activity's state. One critical difference between the fragment lifecycle and the activity lifecycle is that fragment lifecycle methods are called by the hosting activity, not the OS. Fragments are the activity's internal business, the OS knows nothing about the fragments.

There are two approaches to host a UI fragment in an activity:

  • add the fragment to activity's layout
  • add the fragment in the activity's code
The first approach is known as using a layout fragment. It is simple but inflexible. Adding the fragment to the activity's layout hard-wires the fragment and its view to the activity's view and cannot swap out that fragment during the activity's lifetime.
(continue after C13...)

The second approach is the more complex way to host, but it is the only way to have control at runtime over the fragments. You will be adding a UI fragment in the hosting activity's code, but you still need to make a spot (FrameLayout) for the fragment's view in the activity's view hierarchy. Notice that the container view is completely generic; it does not name any classes, so we can use the same layout to host other fragments.

Creating a UI Fragment
The steps to creating a UI fragment are the same as those we followed to create an activity:

  • compose an interface by defining widgets in a layout file
  • create the class and set its view to be the layout that you defined
  • wire up the widgets inflated from the layout in code
There are a couple of things to notice in implementing Fragment.onCreate(Bundle).
First, Fragment.onCreate(Bundle) is a public method whereas Activity.onCreate(Bundle) is protected. Fragment.onCreate(...) and other Fragment lifecycle methods must be public because they will be called by whatever activity is hosting the fragment. 
Second, similar to an activity, a fragment has a bundle to which it saves and retrieves its state. You can override Fragment.onSaveInstanceState(Bundle) for your own purpose just like with Activity.onSaveInstanceState(Bundle).
Third, what does not happen in Fragment.onCreate(..): you do not inflate the fragment's view. You configure the fragment instance in Fragment.onCreate(...), but you create and configure the fragment's view in another fragment lifecycle method:

  public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)

Adding a UI Fragment to the FragmentManager
When the Fragment class was introduced in Honeycomb, the Activity class was changed to include a piece called the FragmentManager.
The FragmentManager handles two things: a list of fragments and a back stack of fragment transactions.

Fragment transactions are used to add, remove, attach, detach, or replace fragments in the fragment list. They are the heart of how you use fragments to compose and recompose screens at runtime.




No comments:

Post a Comment