Working with Fragments in Android

Now that we have understood what fragments are, its time for a practical example. To create a fragment, we have to define a fragment class, which extends the class Fragment and overrides the necessary methods to create the fragment.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;

public class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_view, container, false);
    }
}

In the code above, fragment_view layout is the layout of the fragment which is generally defined in a separate XML file with name fragment_view.xml


To add a fragment to any activity, you can follow any of the following 2 approach:

  1. Specify the fragment directly in the main layout XML file. Basic fragment code in XML looks like:
    <fragment
        android:name="com.studytonight.android.fragments.ExampleFragment"
        android:id="@+id/fragments"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    Where the attribute android:name will hold the fully qualified name of the fragment class.

  2. Or, you can use a FrameLayout to add the fragment at runtime to your activity. We will discuss this approach in detail, but first, lets learn how to implement a basic fragment in our android app.

Basic Implementation of Fragment

In this example we will see how to add a fragment to an activity, by adding the fragment directly in our app's main layout XML file. In this example we will create 2 fragments and will add them to our main activity.

Below is the code for our activity_main.xml file or the main layout XML file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" > 
    
    <fragment  
        android:id="@+id/fragmentOne"  
        android:name="com.studytonight.fragmentexample.FragmentOne"  
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_weight="1" /> 
  
    <fragment  
        android:id="@+id/fragmentTwo"  
        android:name="com.studytonight.fragmentexample.FragmentTwo"  
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_below="@id/fragmentOne" />
  
</RelativeLayout>  

Layout of the first fragment will be defined in fragment_one.xml file.

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    android:background="#2c2e43" >  
  
    <TextView  
        android:id="@+id/textViewOne"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content" 
        android:textColor="#FFFFFF"
        android:gravity="center_horizontal"
        android:text="First Fragment" />
  
</LinearLayout>  

And the corresponding fragment class FragmentOne will be:

package com.studytonight.fragmentexample;  
  
import android.app.Fragment;  
import android.os.Bundle;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
  
public class FragmentOne extends Fragment {  
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) 
    {  
        // TODO Auto-generated method stub  
        return inflater.inflate(R.layout.fragment_one, container, false);  
    }  
  
}

Similarly, the layout XML file and the class for the second fragment will be:

fragment_two.xml

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    android:background="#ff9100" >  
  
    <TextView  
        android:id="@+id/textViewTwo"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"
        android:textColor="#FFFFFF"
        android:gravity="center_horizontal"
        android:text="Second Fragment" />
  
</LinearLayout>  

FragmentTwo.java

package com.studytonight.fragmentexample;  
  
import android.app.Fragment;  
import android.os.Bundle;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
  
public class FragmentTwo extends Fragment {  
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) 
    {  
        // TODO Auto-generated method stub  
        return inflater.inflate(R.layout.fragment_two, container, false);  
    }  
  
}

Finally, the code for the main actvity class MainActivity.java will be as follows:

package com.studytonight.fragmentexample;
  
import android.os.Bundle;  
import android.app.Activity;  
import android.view.Menu;  
public class MainActivity extends Activity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
    }  
}

Once everything is in place, run the android app to see the output.


Output Screen

Basic Fragment Example


Updating Fragment at Runtime

We can also add, remove or update a fragment component in an activity at runtime too. For adding a fragment at runtime, we have to use FrameLayout in out main layout XML file to define the position where we want to add the fragment.

To add/replace/remove a fragment at runtime, FragmentManager and FragmentTransaction to gracefully perfrom the operation of adding, replacing and removing fragments.

Following is how we add a FrameLayout to our layout XML file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" > 
    
    <FrameLayout  
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" /> 
  
</RelativeLayout>  

And this is how we use the fragment manager and transaction classes:

// get fragment manager
FragmentManager fm = getFragmentManager();

// add a new fragment
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.your_placehodler, new FragmentOne());
// commit the change
ft.commit();

// replace a fragment
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.your_placehodler, new FragmentTwo());
ft.commit();

// remove a fragment
Fragment fragment = fm.findFragmentById(R.id.fragmentTwo);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();

This can be used, when on click of some button etc we have to show different information, in that case we can update the fragment on button click.

You must be thinking, Why we need a Manager and Transaction class for updating or adding a fragment? Well, as a fragment is loaded asynchronously, and the changes to the activity are being made at runtime, hence to take care of these factors, FragmentTransaction class is used, which performs all the operation in a transaction, which means, if anything goes wrong, it will revert back the UI to the last stable state.