Android Adventures - Fragments And XML
Written by Mike James   
Thursday, 27 February 2014
Article Index
Android Adventures - Fragments And XML
Blank Activity Template
Summary

The Blank Activity Template

Now is the time to find out about the Blank Activity Template and its ability to include a Fragment automatically in your project.

Thre are many arguments for even the simplest Android application using a Fragment for its UI. Even though you might not need it when you first creat the app they have this tendency to grow and sooner or later you will have to introduce Fragments to make it work properly. So much better to start out with a design that includes a Fragment. However including a Fragment in a simple project when you are just trying to learn about Android doesn't make things easy - and it is for this reason we have avoided using a Fragment..

If you create a new project using the Blank Activity Template  and select the Include a Blank Fragment option you will see a project structure that has an additional layout file - fragment_main.xml as well as an activity_main.xml layout. You should now have no problem understanding these two layout files and how they are going to be used.  

The main layout just has a single container - a FrameLayout. You can mostly ignore this layout as it is really just there to host the Fragment's layout.  It you look at the fragment_main.xml layout you will see that it has a single TextView initialized to "Hello World". This is where you put all of the UI widgets that you have, until now places on the Activity's layout. 

What might puzzle you is where is the class for the Fragment?

For reasons of trying to make the project simpler the Fragment's class is included in the MainActivity.java file. In nearly all cases you should split this out into its own file - if you don't do it initially you will have to do it sooner or later as the lines of code mount up. There is a very easy way to move the Fragment with the help of Android. 

If you look at the code in the MainActivity.java file you will discover, a the end:

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;
 }
}

You should be able to recognise and understand the way that this class is implemented. It simply inflates the fragment_main.xml class. The only difference is the inclusion of a parameterless constructor which all Fragments are supposed to have. So far we have been relying on the parent class of any Fragment's we have been creating to supply this but it is usually a good idea to add it explicitly.

To move this Fragment class to its own file simply place the cursor in the class definition and select Refactor,Move. Select

Move inner class PlaceholderFragment to upper level

which is the default.

 

refactor

 

Finally this is your chance to assign a new and more meaningful name to the Fragment class.

 

refactor2

 

When you click Refactor the class will be moved to its own file and any name change you made will be implemented throughout the project.

For the sake of simplicity the rest of the description of the project will leave the Fragment un-refactored and as the template generated it.

If you look up to the start of the file you will discover that the Activity onCreate is also familiar: 

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();
 }
}

You can see that this is exactly what we have been using to add the Fragment to the Activity's UI in our hand made examples. 

If you look carefully there are two small differences. The Activity is declared to inherit from ActionBarActivity and not the usual base Activity class and for some reason getFragmentManager has become getSupportFragmentManager. The reasons for these changes is that this generated code is designed to work with versions of Android before Honeycomb 3.0. This is a subject we have ignored so far by insisting on Honeycomb as the lowest supported SDK. We need to look at this in more detail - see the next section.

So how do you use this Fragment based project?

If you don't want to do anything clever with Fragments you can mostly ignore the Activity's existence. You can use the designer to place UI Widgets on the Fragment and work with those UI Widgets in the usally way writing all your code in the Fragment's onCreateView using getActivity where necessary. 

However now that you know how Fragments work you will, of course, want to keep code that is specific to the Fragment within the Fragment and code that is more general withing the Activity. 

It is also worth noting at this stage that there is a Fragment template that can be used to add any number of Fragments to a project. This is discussed in detail in the next chapter.

The Support Library

The Simple Blank template introduces the use fo the support library for Fragments and now is a good time to discuss it and how to use it.

A number of the newer features in Android are supported on older versions by the use of a support library that has to be compiled into the project. If you decide to support earlier versions of Android then the support library will make you app a big bigger than it needs to be on the latest version of the operating system.

However, the cost of not using the support library is that your app wont work on earlier versions. Most programmers decide that the support library is worth the inconvenience of larger code so as to enable one runtime package to work on the widest possible Android devices.

Let's take a look at how Fragments are supported on versions of Android before Honeycomb. 

The first things you have to change are the libraries you import:

Android 3 or later              Support
android.app.Activity      ->    android.support.v4.app.
                                                          FragmentActivity
android.app.

FragmentTransaction   ->   android.support.v4.app.
                                                                  FragmentTransaction

android.app.Fragment   ->   android.support.v4.app.Fragment

You also need to change your Activity so that it inherits from FragmentActivity or one of its child classes that support other newer features such as ActionBarActivity. 

The only other change you need to make is to use getSupportFragmentManager in place of getFragmentManager. 

If you make these changes or make use of the support library right from the start you app will work on all versions of Android including Honeycomb and later.

In the remainder of this and other chapters we will use the native Fragment code present in the Android OS. Of course this means that the programs will not run on any Android version earlier than 3.0, aka Honeycomb, but the changes needed to make them do so are trivial. 

Androidgears

Adding A Fragment In XML

Although it generally isn't as useful as creating Fragments in code, you can also treat them as if they were standard UI components and include them in an XML layout file. 

Android Studio makes this very easy and even allows you to use the Designer to view the embedded Fragment and edit it within the layout.

The big disadvantage of including a Fragment within an XML layout is that the Fragment cannot be removed, i.e. it is a static part of the layout.

The advantage  of including the Fragment in the XML layout is that you don't have to modify the code of the Activity to use the Fragment.

Let's see how this works.

When you add a Fragment to an XML layout it is the Java code defining the Fragment, i.e the your Fragment class that you make reference to in the XML. It is up to the Fragment  class to deal with its own XML layout or to generate the View hierarchy in code. 

Suppose we have a new Simple Blank Activity project and we add a new class inheriting from Fragment and making use of a new XML layout file:


public class myFragment extends Fragment {
 @Override
 public View onCreateView(
          LayoutInflater inflater,
          ViewGroup container,
          Bundle savedInstanceState) {
  View rootView = inflater.inflate(
    R.layout.my_fragment,container, false);
  return rootView;
 }
}

 

As before, the Fragment's XML file is called my_fragment and it contains a Button and a TextView. 



Last Updated ( Friday, 17 October 2014 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.