This is the third part of a 6 posts series on Fragment oriented application architecture. In the previous post I talked about Transaction BackStack and its management. In this part I am going to talk about Inter-Fragment Communication. It’s a general concept, not deeply linked to the context of this series.

(Sample application’s source code and README)

It’s a communication pattern over which fragments should talk to each other. Ideally, a fragment should never keep a reference of another fragment or even, in best case, of the specific parent activity. So, how would two fragments communicate? Consider the following scene.

fragments1

Selecting an item in Fragment A needs to update UI of Fragment B by sending a message. You would probably get tempted to keep a reference to Fragment B inside Fragment A. Easy way out! But doing so would lead to tight coupling between these two fragments. That ruins the most basic purpose of fragments, i.e., reusability.

To do this communication we can use an interface that is implemented in activity and it’s reference is kept in Fragment A. Following diagram illustrates the communication pattern.

interface

TheActivity implements Communicator interface which requires to override a method that, in turn, calls a method on Fragment B which does the required change in UI of Fragment B. Fragment A can keep a reference to a ‘Communicator’ instance and delegate the task to implementer of the interface. Fragment A might enforce the host Activity to implement Communicator as follows

// ENFORCING IMPLEMENTATION OF INTERFACE

if(!(getActivity() instanceof Communicator)) {
   throw new ClassCastException("Host activity must implement Communicator interface");
} else {
   communicator = (Communicator) getActivity();
}

Sample application has a section on ‘Inter-fragment communication’. In First fragment of this section, enter your name and press ‘See Greetings’ button, app then navigates to next fragment (a replace transaction) where it greets you using your name. So, the name you entered in first fragment has to be sent to second fragment.

Activity implements an interface (GreetingsInterface) which exposes a method to spawn an instance of GreetingsFragment that would show greetings. First fragment would keep an instance of this interface and would call showGreetings(name) method on it. At this point, first fragment has delegated the task to implementer of interface i.e., Home activity in this case. Now it’s up to Home how it handles it.

This communication pattern has been employed throughout the sample app. Check out its other use cases in the code.

Another clean and useful pattern has been involved here, of keeping a static instance(params) method in a fragment class which returns an instance of it with a Bundle of params as arguments.

// STATIC INSTANCE METHOD

public static GreetingsFragment instance(String name) {
    Bundle arguments = new Bundle();
    arguments.putString(EXTRA_NAME, name);
    GreetingsFragment greetingsFragment = new GreetingsFragment();
    greetingsFragment.setArguments(arguments);
    return greetingsFragment;
}

P.S.: Although this is the standard communication pattern in java, in a vast application the number of interfaces might grow huge, resulting into an excessive amount of boiler-plate code. An alternative to this is the concept of EventBus. Check out Otto and Green robot’s EventBus.

In the next post I’m going to talk about Efficiently handling back-press in Fragments.

Share this:

Privacy Preference Center