Friday 8 February 2013

Android Fragments with daynamic Fragment example


FRAGMENTS IN ANDROID

QUESTION 1- What’s a Fragment?

A fragment is a class implementing a portion of an activity.
  • A fragment represents a particular operation or interface running within a larger activity.
  • Fragments enable more modular activity design, making it easier to adapt an application to different screen orientations and multiple screen sizes.
  • Fragments must be embedded in activities; they cannot run independent of activities.
  • Most fragments define their own layout of views that live within the activity’s view hierarchy.
    • However, a fragment can implement a behavior that has no user interface component.
  • A fragment has its own lifecycle, closely related to the lifecycleof its host activity.
  • A fragment can be a static part of an activity, instantiated automatically during the activity’s creation.
  • Or, you can create, add, and remove fragments dynamically in an activity at run-time.

FRAGMENTS – COMES WITH HONEY COMB ANDROID 3.0 OR LATER.

Fragments were added to the Android API in Honeycomb, API 11.
The primary classes related to fragments are:
android.app.Fragment
The base class for all fragment definitions
android.app.FragmentManager
The class for interacting with fragment objects inside an activity
android.app.FragmentTransaction
The class for performing an atomic set of fragment operations
FRAGMENT LIFE CYCLE
As with the Activity class, the Fragment base class is an example of the template method design pattern.
  • The Fragment base class defines a set of methods that you override to provide the custom behavior of your fragment implementation.
Of primary importance are the fragment lifecycle callback methods.


Fragments have a few extra lifecycle callbacks managing interaction with the activity:
onAttach(Activity)
Called when the fragment has been associated with the activity.
onCreateView(LayoutInflater, ViewGroup, Bundle)
Called to create the view hierarchy associated with the fragment.
onActivityCreated(Bundle)
Called when the activity’s onCreate() method has returned.
onDestroyView()
Called when the view hierarchy associated with the fragment is being removed.
onDetach()
Called when the fragment is being disassociated from the activity.

CREATING FRAGMENT CLASS

Each fragment must be implemented as a subclass of Fragment.
Many of the Fragment methods are analogous to those found in Activity, and you should use them in a similar fashion.
onCreate(Bundle)
Initialize resources used by your fragment except those related to the user interface.
onCreateView(LayoutInflater, ViewGroup, Bundle)
Create and return the view hierarchy associated with the fragment.
onResume()
Allocate “expensive” resources (in terms of battery life, monetary cost, etc.), such as registering for location updates, sensor updates, etc.
onPause()
Release “expensive” resources. Commit any changes that should be persisted beyond the current user session.
To provide a layout for a fragment, your fragment’s class must implement the onCreateView() callback method.
  • The Android system invokes this method when it’s time for the fragment to create its layout.
  • This method must return a View that is the root of your fragment’s layout.

public class FirstFragment extends Fragment implements OnClickListener {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.first_fragment,
                                     container, false);

        Button nextButton = (Button) view.findViewById(R.id.button_first);
        nextButton.setOnClickListener(this);

        return view;
    }

    // ...
}
NOTE -- The final false argument to LayoutInflator.inflate() prevents the inflator from automatically attaching the inflated view hierarchy to the parent container. This is important, because the activity automatically attaches the view hierarchy to the parent as appropriate.


STATICALLY” INCLUDEING LAYOUT IN FRAGMENTS

Activity layout --
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>


1- Use the android:name attribute to provide the package-qualified class name of the fragment.
Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted
Supply the android:id attribute with a unique ID.
  • Supply the android:tag attribute with a unique string.
  • If you provide neither of the previous two, the system uses the ID of the fragment’s container view.



Dynamically Adding a Fragment to an Activity

At any time while your activity is running, you can add fragments to your activity layout.
  1. First, use Activity.getFragmentManager() to get a reference to the FragmentManager.
2 Invoke FragmentManager.beginTransaction() to get an instance of FragmentTransaction.
  • Instantiate an instance of your fragment.
  • Use the FragmentTransaction.add() to add the fragment to a ViewGroup in the activity, specified by its ID. Optionally, you can also provide a String tag to identify the fragment.
  • Commit the transaction using FragmentTransaction.commit(). 

For example:
Activity source code

FragmentManager fragmentManager = getFragmentManager()
// Or: FragmentManager fragmentManager = getSupportFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();


HANDLING RUN TIME CONFIGURATION CHANGES
public void onCreate(Bundle savedInstanceState) {
    // ...
    if (savedInstanceState == null) {
        FragmentManager fragmentManager = getFragmentManager()
        // Or: FragmentManager fragmentManager = getSupportFragmentManager()
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        ExampleFragment fragment = new ExampleFragment();
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();
    }
}
SAVING FRAGMENT STATE
The Fragment class supports the onSaveInstanceState(Bundle) method (but not the onRestoreInstanceState() method) in much the same way as the Activity class.

Retaining Fragments Across Activity Re-Creation

By default, when an activity is re-created (such as in response to a run-time configuration change), its fragments are also destroyed and re-created automatically.
Executing Fragment.setRetainInstance(boolean) with a value of true requests the system to retain the current instance of the fragment if the activity is re-created.
  • If set, when the activity is re-created, the fragment’s onDestroy() and onCreate() methods are not invoked.
  • All other fragment lifecycle methods are invoked in their typical sequence.
If you use setRetainInstance(true), then the Bundle argument to onCreateView() and and onActivityCreated() is null because the fragment is not re-created.
“Retained” fragments can be quite useful for propagating state information — especially thread management — across activity instances.
  • For example, a fragment can serve as a “host” for an instance of Thread or AsyncTask, managing its operation.
  • The Activity.onRetainNonConfigurationInstance() method, which has traditionally been used for this purpose, is deprecated as of API 11 in favor of the fragment’s setRetainInstance() capability.

Using Fragments with no Layouts

A fragment is not required to have a user interface.
  • For example, if the sole purpose of a fragment is to maintain state information or manage a thread, it might not need a user interface.
When using a fragment with no user interface:
  • There is no need to override the onCreateView() method.
  • You must add the fragment to the activity using FragmentTransaction.add(Fragment, String), providing a unique String tag to identify the fragment.
For example:
Activity source code
FragmentManager fragmentManager = getFragmentManager()
// Or: FragmentManager fragmentManager = getSupportFragmentManager()
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
BackgroundFragment fragment = new BackgroundFragment();
fragmentTransaction.add(fragment, "thread_manager");
fragmentTransaction.commit();


Finding Fragments

The FragmentManager class has methods for finding a fragment contained within an activity:
findFragmentById(int id)
Finds a fragment with the specified ID.
findFragmentByTag(String tag)
Finds a fragment with the specified tag.
Both of these methods return a reference to the fragment, or null if no matching fragment is found.

Fragment Operations

You can perform many other operations on dynamic fragments other than adding them to an activity, such as removing them and changing their visibility.
  • Each set of changes that you commit to the activity is called a transaction.
  • You perform fragment operations using the methods in the FragmentTransaction class. Methods include:
    add()
    Add a fragment to the activity.
    remove()
    Remove a fragment from the activity. This operation destroys the fragment instance unless the transaction is added to the transaction back stack, described later.
    replace()
    Remove one fragment from the UI and replace it with another.
    hide()
    Hide a fragment in the UI (set its visibility to hidden without destroying the view hierarchy).
    show()
    Show a previously hidden fragment.
    detach() (API 13)
    Detach a fragment from the UI, destroying its view hierarchy but retaining the fragment instance.
    attach() (API 13)
    Reattach a fragment that has previously been detached from the UI, re-creating its view hierarchy.

Performing Fragment Transactions

To perform a fragment transaction:
  1. Obtain an instance of FragmentTransaction by calling FragmentManager.beginTransaction().
  2. Perform any number of fragment operations using the transaction instance.
    Most of the FragmentTransaction operations return a reference to the same FragmentTransaction instance, allowing method chaining.
  3. Call commit() to apply the transaction to the activity.


1 comment: