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:
- 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.
- 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
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.