Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Building a UI Using Android 3.0 Fragments in Android 1.6 and Later

Author: Saketkumar Srivastav -- Published? true -- FormatLanguage: W

Problem:

You want to add Fragments to the UI in Android 2.0+ versions, though they were originally only available in 3.0+. Fragments, as the name suggests, are nothing but the small chunks of UI which constitutes a single activity. It can be treated as individual portlets of a portal page. It is very similar to activity in terms of its looks, lifecycle, etc but it is also different than Activity in the sense that 'A fragment should always reside in an Activity'; fragments cannot exist independently as Activities.

Solution:

The Fragments API was not supported by previous versions to Android 3.0. When Google released the compatibility package, it was possible to build applications using this Fragments API.

Discussion:

To create a Fragment, we need to extend the class with Fragment. There are different kinds of Fragments available such as: ListFragment ( ListActivity) DialogFragment ( Dialog Interface) PreferenceFragment ( PreferenceActivity)

Lets start with the FragmentTestActivity class.

In onCreate() method we set the list adapter to hold a string array of magazine titles of EFY group. We also set the listener on the list items so that we can perform some action when an item from the list is clicked. 

In the onItemClickListener() method we perform the main task of managing the Fragment. We obtain the instance of the fragment passing the position of the clicked item. Now we need to replace the fragment element that we have in main.xml with the new fragment TestFragment which has a meaning full UI associated with it. To accompolish this we get the instance of FragmentTransaction class, this API allows us to add, remove and replace a fragment programmatically. We replace the R.id.the_frag which corressponds to the <fragment> element of main.xml with the newly created fragment 'f' setTransition() method signifies the kind of transition that happens with the fragment. addToBackStack() method adds the fragment transaction to back of the fragment stack so that when the back button is pressed on the device, you go to the last transaction of the fragment and not exiting the application. After all the transaction is being made we commit the transaction.

Now let us setup the fragment class, the TestFragment class. We initialize the position of the clicked item from the list to a variable magznumber. As we discussed earlier if a fragment is being associated with a UI then onCreateView() method is used to inflate the view to the fragment. Here, we create a linear layout for the fragment and then load it with the appropriate image of the magazine in an ImageView and this ImageView is added to the linear layout.

FragmentTestActivity.java

public class FragmentTestActivity extends FragmentActivity implements OnItemClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ListView l = (ListView) findViewById(R.id.number_list);
        ArrayAdapter<String> magzTitles = new ArrayAdapter<String>(getApplicationContext(),
        		android.R.layout.simple_list_item_1, new String[]{"Electronics For You", 
        															"Linux For You", 
        															"Facts For you"});
       /* ArrayAdapter<String> magzTitles = new ArrayAdapter<String>(getApplicationContext(),
        		android.R.layout.simple_list_item_1, R.array.magz_titles);*/
        l.setAdapter(magzTitles);
        l.setOnItemClickListener(this);
    }

	/**
	 * Called when a number gets clicked
	 */
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		
		Fragment f = new TestFragment(position+1);
    	
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.the_frag, f);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.addToBackStack(null);
        ft.commit();
	}
}

TestFragment.java

public class TestFragment extends Fragment {
    
	private int magznumber;
    
    public TestFragment() {
    	
    }

   /**
    * Constructor for being created explicitly
    */
   public TestFragment(int position) {
	   	this.magznumber = position;
    }

    /**
     * If we are being created with saved state, restore our state
     */
    @Override
    public void onCreate(Bundle saved) {
        super.onCreate(saved);
        if (null != saved) {
        	magznumber = saved.getInt("magznumber");
        }
    }
    
    /**
     * Save the number of Androids to be displayed
     */
    @Override
    public void onSaveInstanceState(Bundle toSave) {
    	toSave.putInt("magznumber", magznumber);
    }

    /**
     * Make a grid to view the magazines 
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
    	
    	Context c = getActivity().getApplicationContext();
    	
        LinearLayout l = new LinearLayout(c);
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 0);
        
        l.setLayoutParams(params);
        
        ImageView i = new ImageView(c);
        
        switch(magznumber){
        case 1:
        	i.setImageResource(R.drawable.efymag);
        	break;
        case 2:
        	i.setImageResource(R.drawable.lfymag);
        	break;
        case 3:
        	i.setImageResource(R.drawable.ffymag);
        	break;
        }
    	
    	l.addView(i);
        
        return l;
    }
}

See Also:

http://developer.android.com/guide/topics/fundamentals/fragments.html

Download:

The source code for this project can be downloaded from https://github.com/SaketSrivastav/AndroidFragmentDemo.
gurung_v 2011-10-28 23:23:11.919 Thanks for the great fragment example. But, when I change the phone orientation from landscape to portrait or vice versa, the application crashes. What can be the reason ?