Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Communication between Android Fragments

In this article will be addressed as a Fragment communicate with each other, how the information is passed and as another Fragment receives

Fragments are pieces of code that has a very similar to the Activity life cycle. Its creation was necessary because as the screens of tablets are larger than the cell, a better space management was needed.

To better understand the operation of a Fragment need to know their life cycle that will dictate their behavior. In this article we will see how the information is passed and how the other receives Fragment using Android Studio.

Basically, for two fragments communicate, you need to make a Fragment A reference to the Fragment B and everything is resolved. However, as a good practice is the reuse of Fragment, it starts to not work because it will be with a high coupling and its reusability would be very low. The main idea is Fragment their possible reuse in another Activity for example. This communication problem can be solved by using an Event Carrier, which is an interface that contains any method which will be responsible for loading the event of a Fragment to the other through the Activity. Look at Listing 1 for better clarification.

Listing 1. Communication between fragments

  public interface Communicator{
              public void event(String data);
  }
   
  public class MainActivity extends Activity implements Communicator{
              // Obrigatory implementation of event method
              public void event(String data){
                  // Code that defines the method
              }
  }
   
  public FragmentA extends Fragment{
              Communicator communicator;
   
              public void onAttach(Activity activity){
                          communicator = (Communicator)activity;
              }

Notice that the FragmentA has access through the communicator attribute to the method implemented in MainActivity. One can notice that the onAttach method, present in Fragment lifecycle was used to receive the operating system a reference of the Activity, and how it implements the communicator interface, there is no problem in making a cast to assign it to object.

There are other standards for making that same task, such as the communicator interface could be placed within the class FragmentA, ensuring that the interface would not be exposed more than it should. But that was chosen for its ease of understanding of the steps.

In order to see how the layout files communication will first be created both of the two Fragments as the Activity. Note that very different and distinct colors are placed so that the viewing of each element on the screen as possible. The file names are: activity_main.xml, fragment_a_layout.xml and fragment_b_layout.xml.

Listing 2. Activity Layout Code

  <?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical" android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="#0000FF">
   
      <fragment
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:name="com.home.fragmentflexibleui.FragmentA"
          android:id="@+id/fragment" />
   
      <fragment
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:name="com.home.fragmentflexibleui.FragmentB"
          android:id="@+id/fragment2" />
  </LinearLayout>

The code in Listing 2 defines the Activity and within the two Fragments are placed. Note that this is a static insertion, ie these Fragments can not be replaced at runtime. The Activity of this background color will be a Dark Blue.

Listing 3. FragmentA layout code

 <?xml version="1.0" encoding="utf-8"?>
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent" android:layout_height="match_parent"
      android:background="#FFCC00">
   
      <ListView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/listView"
          android:layout_alignParentLeft="true"
          android:layout_alignParentStart="true"
          android:layout_alignParentTop="true" />
  </RelativeLayout>

Listing 3 shows the FragmentA, the code that implements a ListView where we can select values. The background color of this Fragment is orange.

Listing 4. FragmentB layout code

 <?xml version="1.0" encoding="utf-8"?>
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent" android:layout_height="match_parent"
      android:background="#00FF00">
   
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:textAppearance="?android:attr/textAppearanceLarge"
          android:text="Large Text"
          android:id="@+id/textView"
          android:layout_alignParentTop="true"
          android:layout_alignParentLeft="true"
          android:layout_alignParentStart="true" />
  </RelativeLayout>

This code in Listing 4 defines the screen just a Text Oversize View to display selected information on FragmentA. The background color of this Fragment is green.

What will be done now is popular mass data to be displayed. In Android Studio, within the directory res->values, open the string.xml file and place the mass of data that will be accessed by the application. This file should already be populated with some information. Between the <resource> and </ resource> Enter the contents of Listing 5.

Listing 5. Mass data

 <string-array name="titulos">
          <item>Gandalf</item>
          <item>Aragorn</item>
          <item>Legolas</item>
          <item>Gimli</item>
          <item>Arwen</item>
      </string-array>
   
      <string-array name="descrip">
          <item>Gandalf was... </item>
          <item>Aragorn II, sono f Arathorn was... </item>
          <item>Legolas was the son of Thranduil, King of the Woodland Realm of Northern Mirkwood, who appears as "the Elvenking" in The Hobbit. Thranduil ruled over the Silvan Elves or "Wood-elves" of Mirkwood.</item>
          <item>Gimli was a member of Durin's Folk who volunteered to accompany Frodo Baggins as a member of the Fellowship of the Ring on the quest to destroy the One Ring. He was an honourable, wise, and stalwart warrior.</item>
  <item>Arwen Undómiel was a fictitious character... </item>   
  </string-array>

Now the Java code that makes all the magic happen will be implemented: the communicator, the activity and the fragments will be defined with a small difference, because here the parameter is an integer and not a String, as shown in Listing 1, since we are vector index that was set in strings.xml file.

Listing 6. Comunicator interface code

 package com.home.fragmentflexibleui;
   
  /**
   * Created by mrbool on 9/24/15.
   */
  public interface Communicator {
      public void respond(int id);
  }

Listing 6 is the Event Carrier interface and will be implemented in the Activity.

Listing 7. Activity Code

 package com.home.fragmentflexibleui;
   
  import android.app.Activity;
  import android.app.FragmentManager;
  import android.os.Bundle;
   
  /**
   * Created by mrbool on 9/24/15.
   */
   
  public class MainActivity extends Activity implements Communicator{
   
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
      }
   
      @Override
      public void respond(int data) {
          FragmentManager manager = getFragmentManager();
          FragmentB frag = (FragmentB)manager.findFragmentById(R.id.fragment2);
          frag.change(data);
      }
  }

Listing 7 shows the code Activity, where the onCreate is called and the layout is attached to the Activity, as usually happens in Android applications.

Listing 8. Method responds

 @Override
      public void respond(int data) {
          FragmentManager manager = getFragmentManager();
          FragmentB frag = (FragmentB)manager.findFragmentById(R.id.fragment2);
          frag.change(data);
      }

In Listing 8 we have the method signature answers contained within the interface. Its implementation requires a FragmentManager object type is defined and which receives a return call from getFragmentManager() method, which is responsible for managing the Fragments.

In FragmentB frag = code (FragmentB)manager.findFragmentById(R.id.fragment2); It is instantiated FragmentB a type of object that will receive the return of findFragmentById method, which is passed the id of the Fragment in question (in the case FragmentB). The cast is important in this case, so it can not be forgotten. Finally, the change method is called passing as a parameter the data, but only explain more about when implemented FragmentB code.

Listing 9. FragmentA code

 package com.home.fragmentflexibleui;
   
  import android.app.Activity;
  import android.app.Fragment;
  import android.os.Bundle;
  import android.support.annotation.Nullable;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.AdapterView;
  import android.widget.ArrayAdapter;
  import android.widget.ListView;
   
  /**
   * Created by mrbool on 9/24/15.
   */
  public class FragmentA extends Fragment implements AdapterView.OnItemClickListener{
      private ListView list;
      private Communicator comm;
   
      public void onAttach(Activity activity) {
          super.onAttach(activity);
          comm = (Communicator)activity;
      }
      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          return inflater.inflate(R.layout.fragment_a_layout, container, false);
      }
   
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
   
          list = (ListView) getActivity().findViewById(R.id.listView);
         ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),R.array.titulos,android.R.layout.simple_list_item_1);
          list.setAdapter(adapter);
          list.setOnItemClickListener(this);
      }
   
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          comm.respond(position);
      }
  }

Listing 9 shows the code of the FragmentA responsible for displaying the list on the screen and send the data to the Fragment B. Note that the Comunicator is set at the beginning of the class as a private attribute, it will be used only within that class.

Listing 10. onAttach method

  public void onAttach(Activity activity) {
          super.onAttach(activity);
          comm = (Communicator)activity;
      }

In Listing 10 can be noted that the communicator type of object receives the Activity in the Fragment is contained, it can be done only because the Activity implements the Communicator interface. Here our Fragment already has the reference you need to pass the information, but remember to not run any UI operation in this method, it is not guaranteed that the UI is ready.

Listing 11. onCreateView method

 @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          return inflater.inflate(R.layout.fragment_a_layout, container, false);
      }

In Listing 11 has the onCreateView method responsible for attaching the XML layout to Fragment using the inflate method, as it will "transform" a layout on a Java object of type View.

When you create a view "public View onCreateView (LayoutInflater inflater, ViewGroup container, savedInstanceState Bundle) {" return is a type view, so you must make a inflate, which is a method contained within the LayoutInflater class, responsible for "inflating "the layout XML. In other words, it transforms the XML into a type View object. It is an expensive process because it takes the XML and creates a Java this XML object, by setting all attributes, and recursively do this for all the child tags that are in XML.

Listing 12. onActivityCreated method

 @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
   
          list = (ListView) getActivity().findViewById(R.id.listView);
         ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),R.array.titulos,android.R.layout.simple_list_item_1);
          list.setAdapter(adapter);
          list.setOnItemClickListener(this);
      }

It is recommended that the Fragment of UI operations are performed from the onActivityCreated method of Listing 12, because it ensures that the Activity has been completely created. Here is placed the title of Array created earlier in strings.xml file.

Within a ListView object type must attach the element that represents the list in the Fragment layout XML, for it is used findViewById method passing reference to that element. Thus, a ArrayAdapter type of object should be created. As the Array defined in the mass of data within the strings.xml file, you must load the data that are in there using the static method createFromResource, passing three parameters: first Activity, according to the Array that is in the file, and third the list layout that will be displayed.

Now what will be done is pegging the Array detítuloscom an Android layoutbásico that shows a simple list. Finally, what will be done is connect the ArrayAdapter with the ListView object, so it can be shown in oconteúdo screen array.

You can also create a custom adapter, where the data is brought from the SQLite database, but as is the focus of this article does not, see Adapter Android Customized for inserting images in SQLite.

Listing 13. onItemClick method

 @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          comm.respond(position);
      }

In Listing 13 the listener identify the position that was clicked and pass as a parameter in the method responds. Remember that this method is defined in the Activity. Thus the FragmentA class is complete.

Listing 14. FragmentB code

 package com.home.fragmentflexibleui;
   
  import android.app.Activity;
  import android.app.Fragment;
  import android.content.res.Resources;
  import android.os.Bundle;
  import android.support.annotation.Nullable;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.TextView;
   
  /**
   * Created by mrbool on 9/24/15.
   */
  public class FragmentB extends Fragment {
      private TextView text;
      private Activity activity;
   
      public void onAttach(Activity activity){
          super.onAttach(activity);
          this.activity = activity;
      }
   
      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          return inflater.inflate(R.layout.fragment_b_layout, container, false);
      }
   
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          text = (TextView) activity.findViewById(R.id.textView);
      }
   
      public void change(int data){
          Resources res = getResources();
          String[] desc = res.getStringArray(R.array.descrip);
          text.setText(desc[data]);
      }

In Listing 14 can be noted that the FragmentB has some very similar methods FragmentA: the onAttach copy a reference to the Activity that will be used in onActivityCreated method and onCreateView method does the same thing in FragmentA.

The OnActivityCreate method also has the same function as the FragmentA, with the exception here will be the link between a TextView object responsible for displaying the elements on the screen. Note that, for didactic purposes, here was made the reference to the type of object Activity instantiated earlier in onAttach to simplify. The onAttach method could be deleted and the object Activity type could be replaced by getActivity() method.

Listing 15. Method change

 public void change(int data){
          Resources res = getResources();
          String[] desc = res.getStringArray(R.array.descrip);
          text.setText(desc[data]);
      }

Listing 15 shows the method responsible for displaying on the screen the contents of the array whose content was sent by the fragmenting. Here again, the resources are loaded by getResources() method, the array of strings containing data the mass regarding the description is stored in an Array object of type String, and finally, the TextView object type displays the data in the reference screen the position of the array sent by the fragmenting.

Figures 1 and 2 show the results which vary according to the selected option.

Figure 1. Final Result 1

Figure 2. Final Result 2



Web developer and passioned for web design, SEO and front end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login