Wednesday, October 10, 2012

Fragments in Android

WHY FRAGMENTS ?

When Fragment wasn't in android , developers were able manage UI flow only at the Activity level. All UI components were Views (mentioned in XML layout and part of Activity) and there was no way to manage these components separately. As a result all view management code were in a single file i.e. Activity class.  

"With fragment approach, we can now remove View management code from Activity and place them in their respective Java classes. So, a pretty neat approach for code managemen"

In Android, a configuration change (which includes turning the phone sideways to view the screen in the landscape direction) causes the currently running activity to be stopped, reloaded, and re-rendered using the new configuration parameters.  (I'm sure iOS developers will be quick to point out this "feature" is missing in their stack.)  In doing so, your app will lose all the state information from the activity instance that was originally running.  Wouldn't it be nice to keep that around? 
 
Fragments are UI components (though it is possible to have non-UI fragments) that have the ability to retain state across configuration changes.  Fragments must always be associated with an activity, but with a quick call to setRetainInstance(true), the fragments that were associated with an activity will re-attach themselves to the new instance of an activity and retain their previous state.  
 

WHAT IS FRAGMENTS ?

"A Fragments represent a behaviour or portion of user interface in an activity. It is a modular section of an activity that has its own life cycle but it's life cyle is directly affected by the Activity that hosting it."

The primary advantage of Fragments is the ease with which you can create dynamic and flexible UI designs that can be adapted to suite a range of screen sizes — from small-screen smartphones to tablets.

Each Fragment is an independent module that is tightly bound to the Activity into which it is placed. Fragments can be reused within multiple activities, as well as laid out in a variety of combinations to suit multipane tablet UIs and added to, removed from, and exchanged within a running Activity to
help build dynamic UIs.

Fragments provide a way to present a consistent UI optimized for a wide variety of Android device types, screen sizes, and device densities.



 How do we add a fragment ? 

Define a container layout (LinearLayout) and add [fragment] tag inside. Inside the fragment tag, we need to mention respective Fragment Java class.
[LinearLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:id="@+id/list_frag_layout"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="#FFFFFF"]
       [fragment
            android:name="com.pras.frags.MyListFrag"
            android:id="@+id/list_frag"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/]
[/LinearLayout]

Here list_frag_layout is the container layout of list_frag.
We need to attach this layout with an Activity. The Activity class is the parent of the fragment and it gives callback to onAttach() and onContentView() methods of fragment.

 How does the Fragment communicates with Activity ?
 
A fragment can get the instance of its parent Activity by calling getActivity() or during the onAttach() callback, Framework passes the instance of parent Activity to fragment.
You can define an Interface and the Activity should implement that interface. Fragment class can give call to this Interface method to notify any UI event.
An activity can hold multiple Fragments and fragments should communicate via their parent Activity. 

How do I dynamically manage the width/height of Fragment ?
 
To achieve this we need to keep the fragment inside a container layout, just like above. Following code piece set the width of list_frag to 50% of the screen.

    int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int leftFragWidth = (int)(screenWidth * 0.50);
    LinearLayout.LayoutParams leftParm = new LinearLayout.LayoutParams(leftFragWidth, LinearLayout.LayoutParams.MATCH_PARENT);
    findViewById(R.id.list_frag_layout).setLayoutParams(leftParm);

 
How do I switch multiple Fragments ?
 
In this example, when user click on any list item, it switch to Detail Fragment. To switch/replace fragment, we need to use Fragment Transaction and hide the previous i.e. ListFragment. To get the benefit of BACK handling, we'll add this switch transaction to the Back Stack. So user can go to the List pressing the Back key. It is really a nice concept.
Following code piece adds Detail Fragment on View and hides the previous fragment i.e. List. To keep track of this transaction, it will add this in Back Stack and finally commit the transaction.
           // Change List fragment with Detail Fragment
        FragmentManager fm = getFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        // Hide previous fragment
        transaction.hide(fm.findFragmentById(R.id.list_frag));
        // Add this new Fragment into the layout
        DetailFrag detailFrag = new DetailFrag();
        transaction.add(R.id.list_frag_layout, detailFrag);
        // Add to this transaction into BackStack
        transaction.addToBackStack(null);
        // Commit this transaction
        transaction.commit(); 

You can download the complete Fragment example source code from http://code.google.com/p/android-java-sample-code/

No comments:

Post a Comment