In android development, it can happen to pass steps too quickly because it’s wrong to think that the simplest is going to the essential: the code ! It’s a mistake. I often have read articles explaining how to do something and after thinking about it, I could easily understand that it wasn’t the right thing to do. This this is a subjective opinion of course, because for the user, the displayed result is the same but not for the developer.

Use case

You want to develop an android application. You have decided the architecture to implement but you haven’t clearly defined how the elements would communicate with each other. For example, your architecture is a parent activity hosting fragments that will be accessible by clicking on the tabs corresponding to those fragments from a FragmentTabHost. For the moment, no worries, you juste need to create fragments (three fragments that you will name FragmentA , FragmentB and FragmentC). Even before creating these fragments, you naturally began by creating your parent activity that you named ParentActivity (keep it simple but accurate !). In ParentActivity, you declared and instantiated a FragmentTabHost object to specify the fragments you want to appear in.

Regarding navigation from one fragment to another, it’s enough to create a number of view tab corresponding to the number of fragment to be displayed and to specify to our FragmentTabHost the order you want them to appear and which fragment will be attached to the corresponding tab.

You execute your code and you get (in a one shot of course and without warnings !) the following result :

Everything’s good ? So let’s go ! Let’s assume that when you enter FragmentA, by clicking on a SayGoodBye button, you call a function that allows to trigger an action from FragmentA by the way of the listener, in ParentActivity and which a response is finally posted from the ParentActivity to the Fragment.

The listeners

You probably already ever have heard of it to detect (for example) a click on a button, you administered a listener to trigger an action corresponding to this event. What I propose you today is to create our own listeners. Let’s take our example of function that says hello. We will call the sayHello(String message) method in ParentActivity by the way of a listener that we will use in FragmentA. To do this we will create our own listener which is an interface that we’ll call FragmentAListener and in which we’ll declare the sayHello(String message) method like this :

public interface FragmentAListener { public void sayHello(String message); }

Now we’ll declare this listener in our fragment which will serve us to call the sayHello (String message) method previously declared in the interface.

@Override public void onAttach(Context context) {
  super.onAttach(context);
  try {
    if (context instanceof FragmentAListener) {
      listener = (FragmentAListener) context;
    }
  } catch (ClassCastException e) {
    Log.d(MyClassTag , e.getMessage())
  }
}

The onAttach method allows to retrieve a pointer to the containing activity and associate it with the concerned fragment, in our example, the “FragmentA” fragment. It allows the communication from the fragment to the activity.

Let’s see how to use our listener in case we want to call the sayHello(String message) method:

this.listener.sayHello(String message);

At this step, if you execute your code, you will not get any results because you haven’t overloaded the declared method in the FragmentAListener interface. To do this, we will go into ParentActivity and we will implement the FragmentAlistener interface. By doing this, we will override the `sayHello(String message)” method.

public class ParentActivity extends AppCompatActivity implements FragmentAListener {
...

  @Override public void sayHello(String message) {
    Toast.makeText(getApplicationContext(), "It ‘s me" , Toast.LENGTH_SHORT).show();
  }
...
}

All you have to do is to compile your code and click on the Say Hello button of the FragmentA fragment. You should see a toast in which it’s written It's me ! Now, what would be interesting is inform FragmentA the “Say Hello” method has been called.In this case, I propose to use a library named EventBus. It simplifies communication between Activities, Fragments, Threads, Services, etc.

EventBus

To illustrate the use of the EventBus library, we will add a TextView in a FragmentA. This TextView will be refreshed from this last one, by retrieving the value to display there from the event we will have created. To continue, include the following dependency in your build.gradle file :

compile 'de.greenrobot:eventbus:2.4.0'

We have to save the destination object (here onStart () unsubscribe to the FragmentA method you register with EventBus, then don’t forget to ) as a receiver to EventBus, taking into account the life cycle of the activity or fragment. In the “onStop()” method.

public class FragmentA extends Fragment {
  @Override public void onStart() {
    super.onStart();EventBus.getDefault().register(this);
  }

  @Override public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
  }
}

Go into the “sayHello(String message)” method in “ParentActivity” and post the following message:

@Override public void sayHello(String message) {
  Toast.makeText(getApplicationContext(), "It ‘s me" , Toast.LENGTH_SHORT).show();
  EventBus.getDefault().post(newPleaseRefreshEvent("Ok Adèle"));
}

Let’s create our event that will allow us to get the answer since ParentActivity.

public class MessageEvent {
  public String message;

  public MessageEvent(String message){
    this.message = message;
  }

  public String getMessage(){
    return message;
  }
}

Return to FragmentA and refresh the textview with the received response in the event.

/**
 * This method is automatically called when a eventbus event is worked
 * @param event
 */
 @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent(MessageEvent event) {
   this.textview.setText(String.valueOf(event.message));
 }

Conclusion

When developing an application, don’t always follow the solution that seems to be the most obvious, but think about making your code as clean as possible by separating the business code from the rest of the application. In this article we‘ve seen a listener is a simple interface allowing in our case separate the business code from the fragments. This business code is executed in the main activity from the hosted fragment. EventBus is also an excellent way to communicate from one fragment to another or simply to indicate from an activity to a fragment that it must refresh itself. I hope this article has allowed you to discover a new technical approach in the concerning possibilities to establish the communication between an activityg in o fragment.}