Android Fragments in an Activity

In Android development, the Fragment classes are contained within an Activity class. This may be from 1 Fragment to multiple Fragments within an Activity class. The purpose of this tutorial is to get familiar with Android Studio while learning about Android development.

Fragments can be created as;
  • Dynamic
  • Static
Here is an example of creating Fragments within an Activity. The buttons determine which Fragment to be displayed. The Fragment could either be an analog or digital display.

Analog: Galaxy S5 Android 5.0

Digital: Galaxy S5 Android 5.0

The codes are tested with Android Studio 1.4RC3 on MS Windows 8.1 and deployed to Nexus 4 emulator for API 18 and 21. Also tested on Galaxy S5 with Android 5.0.

Step 1:

Open Android Studio and create a new project.
Application name: MyFragmentExample
Click Next

Click Checked for Phone and Tablets
Minimum SDK: choose API 18:Android 4.3 (Jelly Bean)
Click Next

Choose "Blank Activity"
Click Next

Activity Name: MainActivity
Layout Name: activity_main
Title: MainActivity
Menu Resource Name: menu_main
Click checked "Use a Fragment"
Click "Finish"

If you see an error "Rendering problems", just wait until build/compile is completed. For a slower computer, this is expected.

In build.gradle, the targetSDKVersion is chosen as 23 because Galaxy S5 is at Android 5.0.

Step 2:

The file in res/layout/activity_main.xml includes the content_main.xml layout. This in turn uses the layout fragment_main.xml (default layout is RelativeLayout).

Open fragment_main.xml in Text view (see the tab Design / Text at bottom). Delete the text RelativeLaout and enable the quick tips by typing "Line". Choose LinearLayout and press Tab. Change the layout to vertical by adding the line within the LinearLayout;

 android:orientation="vertical"  


Change view to Design (tab Design/Text at bottom). Code should look like;
 xmlns:tools="http://schemas.android.com/tools"  
   android:orientation="vertical"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   tools:showIn="@layout/activity_main"  
   tools:context=".MainActivityFragment">  

Troubleshooting: Missing or not working widgets?
The design view does not appear to update if not using emulator for API 23. Just click and choose emulator for API 23.

 Replace the default TextView (Hello World!) with following buttons.

  <Button   
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:text="@string/analog_text"   
    android:id="@+id/button_analog" />   
   <Button   
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:text="@string/digital_text"   
    android:id="@+id/button_digital" />   

Replace the text values with a new string resource in res/values/strings.xml

Click on the text "Analog", press Alt+Enter. Choose Extract string resource.

Enter Resource name: analog_text
This will create the codes needed in strings.xml. Do the same for text Digital.


Step 3:

In fragment_main.xml switch to Design view and drag a FrameLayout to below the buttons and centre. Double click on the newly added FrameLayout and add id fragment_container. The code should look like;

 <FrameLayout   
    android:layout_width="match_parent"   
    android:layout_height="match_parent"   
    android:layout_gravity="center_horizontal"   
    android:id="@+id/fragment_container">   
  </FrameLayout>   

Step 4:

Right Click java/packagename, choose New-> "Fragment"-> "Fragment blank"
Fragment name: FragmentAnalog
Checked "Create layout XML?"
Layout name: fragment_analog
Click "Finish"

Open fragment_analog.xml in Text view. Change FrameLayout to RelativeLayout.

Delete the TextView

Switch to Design view. From the Palette tools, scroll down and drag AnalogClock to the center for vertical and horizontal. The code generated should look like this;

 <AnalogClock   
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:id="@+id/analogClock"   
    android:layout_centerVertical="true"   
    android:layout_centerHorizontal="true" />   

Open FragmentAnalog.java and replace import android.app.Fragment with

 import android.support.v4.app.Fragment;  

Repeat above steps to create FragmentDigital Fragment. This time, instead of AnalogClock, choose TextClock. The TextClock should produce following;

 <TextClock  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:id="@+id/textClock"  
     android:format24Hour="HH:MM:ss"  
     android:textSize="60sp"
     android:layout_centerVertical="true"  
     android:layout_centerHorizontal="true" />  

For Android API18, the TextClock did not process the format24Hour correctly, instead used the default format. For backwards compatibility, replace android:format24Hour with below;
 android:format12Hour="hh:mm:ss aa"  
 android:format24Hour="kk:mm:ss"  

Step 5:

Open MainActivityFragment.java and add following member variables;

private Button analogButton, digitalButton;

Right click after the constructor (or Alt+Insert), choose "Override methods..."-> "onCreate(savedInstanceState:Bundle):void". Add following lines;

 analogButton = (Button) getActivity().findViewById(R.id.button_analog);  
 analogButton.setOnClickListener(this);  
 digitalButton = (Button) getActivity().findViewById(R.id.button_digital);  
 digitalButton.setOnClickListener(this);  

There should be a wriggly red line at the text "this", click once then press Alt+Enter. Choose "Make MainActivityFragment implement android,view.View.OnClickListener". Choose "onClick(v:View):void" and press "OK".

In the newly created override method onClick, add;

     Fragment f;  
     Log.v(LOG_TAG, "onClick MainActivityFragment");  
     if(v==analogButton){  
       f = new FragmentAnalog();  
     } else {  
       f = new FragmentDigital();  
     }  
     setFragment(f);  


At the top of MainActivityFragment.java, replace/add

import android.support.v4.app.FragmentManager;

Click setFragment, then press Alt+Enter, choose "Create method setFragment" and add following codes;
     FragmentManager manager = getFragmentManager();  
     FragmentTransaction transaction = manager.beginTransaction();  
 //        .setTransition(  
 //            FragmentTransaction.TRANSIT_FRAGMENT_FADE  
 //        );  
     transaction.replace(R.id.fragment_container, f);  
     //transaction.addToBackStack(null);  
     transaction.commit();  


Step 6:

Open MainActivity.java and edit class declaration to implement the OnFragmentInteractionListener as follows;

 public class MainActivity extends AppCompatActivity implements  
     FragmentAnalog.OnFragmentInteractionListener  
     , FragmentDigital.OnFragmentInteractionListener{  
 Add a new member function to implement above.  
 public void onFragmentInteraction(Uri uri){  
     //  
 }  

Compile and run.

Done.

TODO: Make Back button exit to blank main activity screen. Currently pressing the Back button, reverse the Fragment objects one by one.

Reference

Blog Archive