Android Fragment Usage in Android Application Development

Android Fragment Usage in Android Application Development

In this tutorial we are going to learn how to create android Fragment in Android Studio. This will be a long tutorial that will cover different aspects of android Fragment, its importance in android UI design and how to use android Fragment in android application development.

We will start by learning how we can easily create an android Fragment project by using one of the templates provided to us by Android Studio.

We will go further to learn different ways by which we can pass data from a Fragment to a host Activity.

With this knowledge at hand we will proceed to learn how two different Fragments present in a single Activity class can communicate between each other.

We will final learn how to design a Master/Detail layout in android using Fragment.

Before we proceed, it is important for us to learn more and understanding what Fragment is and when to use Fragment in android project.

Android Fragment

Android initiated fragments in Android 3.0 (API level 11), principally to support more dynamic and flexible UI designs on large screens, like tablets. Due to the fact that a tablet’s screen is much larger than that of a handset, there’s more room to combine and exchange UI components.

Fragments permit such designs without the requirement for you to manage complex changes to the view pecking order. By separating the layout of an activity into fragments, you become capable of changing the activity’s appearance at runtime and conserve those changes in a back stack that’s managed by the activity.

Fragment does not run on its own. Every Fragment must be hosted by an Activity class although Fragment has its own Life-cycle but it is resume when its host Activity is resume and it is destroy vice verse.

Fragment can be add, remove and replace in Activity class thus its usage have help to solve some initial problem encounter with Activity like when different views in the same activity wants to pass data to each other.

Android Life Cycle

According to Android developers manual – Though a Fragment’s lifecycle is tied to its owning activity, it has its own wrinkle on the standard activity lifecycle. It includes basic activity lifecycle methods such as onResume(), but also important are methods related to interactions with the activity and UI generation.

The core series of lifecycle methods that are called to bring a fragment up to resumed state (interacting with the user) are:

onAttach(Activity) called once the fragment is associated with its activity.

onCreate(Bundle) called to do initial creation of the fragment.

onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.

onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().

onViewStateRestored(Bundle) tells the fragment that all of the saved state of its view hierarchy has been restored.

onStart() makes the fragment visible to the user (based on its containing activity being started).

onResume() makes the fragment begin interacting with the user (based on its containing activity being resumed).

As a fragment is no longer being used, it goes through a reverse series of callbacks:

onPause() fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.

onStop() fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.

onDestroyView() allows the fragment to clean up resources associated with its View.

onDestroy() called to do final cleanup of the fragment’s state.

onDetach() called immediately prior to the fragment no longer being associated with its activity.

Note: If you choose that the minimum API level your app needs is 11 or higher, you don’t supposed to use the Support Library and can as an alternative use the framework’s built in Fragment class and associated APIs. Just know that this lesson is focused on using the APIs from the Support Library, which use a particular package signature and sometimes to some extent diverse API names than the versions included in the platform.

There are important classes you should know about when working with Fragment in android. The list and what they do is shown below.

android.app.Fragment – The base class for all fragment definitions. When you create your own Fragment it can inherit from this class.

android.app.FragmentManager – The FragmentManager class is use to interact and manipulation of Fragments in their host Activity class. The instance of this class is obtained by calling the getGragmentManager() of the Activity Class.

android.app.FragmentTransaction – The FragmentTransaction class is focus on performing certain operations on Fragment.

It is also important to call the commit() method of the FragmentTransaction whenever it is used.

Creating Android Fragment in Android Studio

We have learn enough of android Fragment. This is time for us to implement most of the knowledge we have added. We are going to use Android studio to create our example android Fragment.

Before we start, the first thing I will do is to list the environment and tools I used in this android tutorial but feel free to use whatever environment or tools you are familiar with.

Windows 7

Android Studio

Sony Xperia ZL

Min SDK 14

Target SDK 19

To create a new android application project, following the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidFragmentExample

Package: com.inducesmile.androidfragmentexample

In the add Activity to mobile window pop-up, select Blank Activity with Fragment

Android Fragment

Keep other default selections.

Continue to click on next button until Finish button is active, then click on Finish Button

Once the project is created, go to your project resources folder > layout folder and double click to open the activity_main.xml layout file. The content of the main layout file is as shown.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
tools:context=".MainActivity"
tools:ignore="MergeRootFrame"
android:layout_height="match_parent" />

It contains a single FrameLayout that will hold the Fragment View components. In the layout folder, you will also see the fragment_main.xml layout file that the Fragment Class will inflate and attached to the main layout container of our application.

The code for the file is as shown.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity$PlaceholderFragment">

<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</RelativeLayout>

You will notice that the layout uses the tools attribute to match the Fragment layout to the main Activity layout described above.

Now let look at our MainActivity.java class below.

package inducesmile.com.androidfragmentexample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;


public class MainActivity extends ActionBarActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

if (savedInstanceState == null) {

getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
}
}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.menu_main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long

// as you specify a parent activity in AndroidManifest.xml.

int id = item.getItemId();

//noinspection SimplifiableIfStatement

if (id == R.id.action_settings) {

return true;

}
return super.onOptionsItemSelected(item);
}

public static class PlaceholderFragment extends Fragment {

public PlaceholderFragment() {
}
@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_main, container, false);

return rootView;
}
}
}

The MainActivity.java class has an inner Fragment class. In order to create a Fragment class, you should create a java class with will inherit from the base Fragment class. In our own situation, our Fragment class is called PlaceholderFragment.

The below code snippet is used to create the Fragment class

import android.app.Fragment;

class PlaceholderFragment extends Fragment {

}

To create the Fragment UI components, the Fragment method public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) is override . The LayoutInflate object passed as a parameter to the method is use to inflate the xml layout file of the Fragment class. The code is as shown.

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_main, container, false);

return rootView;

}

In other to attach the Fragment class to its host activity, we will first check is the Fragment instance has been attached already using the saveInstanceState instance.

if (savedInstanceState == null) {

getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();

}

The getSupportFragmentManager() returns an instance of FragmentManager which will use a FragmentTransaction operation to add, replace or remove a Fragment. Finally, the commit() method is called to execute the process.

Communicating Between Fragments And Activities

In the next example, we will cover how Fragments communicate with its host Activity. There are few ways to achieve this like calling the getActivity() method in the Fragment class to get the instance of the host Activity. With the Activity handle obtained, you can then call any accessor methods of the Activity class.

In this example we will make use of the an Interface. When a Fragment needs to pass data to its containing Activity, the Fragment class needs to implement an Interface to handle the data. For it to work, the host Activity class must implement the interface methods.

We will create a new Fragment class called BlankFragment and let the class extends the base Fragment class.

The Fragment class will contain an interface which will be implemented by the host Activity. The interface is as shown.

public interface OnFragmentInteractionListener {

public void onFragmentInteraction(String uri);

}

The onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) method of the Fragment will inflate a layout that contains all view components of the Fragment.

The onAttach(Activity activity) method of the base Fragment class is override in such a way that it force the host Activity to implement the interface.

The complete code for the Fragment class is shown below.

package inducesmile.com.androidfragmentexample;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class BlankFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    public BlankFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_blank, container, false);
        Button clickButton = (Button)view.findViewById(R.id.button);
        clickButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(), "Fragment Button Click", Toast.LENGTH_LONG).show();
                onButtonPressed("Fragment Button Click");
            }
        });
        return view;
    }

    public void onButtonPressed(String  uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnFragmentInteractionListener {
        public void onFragmentInteraction(String uri);
    }

}

The inflate xml Layout file for the Fragment class consist a FrameLayout and a Button View. When the button is click, it passes a string value to the activity class.

The code for the fragment_blank.xml layout file is as shown

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="inducesmile.com.androidfragmentexample.BlankFragment">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Make Toast"
        android:padding="32dp"
        android:layout_gravity="center" />
</FrameLayout>

With that we have made a little change in our MainActivity.java file. The updated version of the class and interface implementation is shown below.

package inducesmile.com.androidfragmentexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener {

    private BlankFragment blankFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().add(R.id.container, new BlankFragment()).commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onFragmentInteraction(String uri) {
        System.out.println(uri);
    }
}

Now, when you run your application you will see the interface that looks similar to the sample that was shown earlier on.

You can download the code for this tutorial below. If you are having hard time downloading the tutorials, kindly contact me.

Remember to subscribe with your email so that you will be among the first to receive our new post once it is published.

No Responses

Add a Comment