MVP Fragment navigation (from inside fragments)

MVP is the one of the most used architectural patterns in Android to separate view logic from the business logic. But aside its beneficial parts he comes with some obstacles in here or there.

One obstacle in android programming and not only in MVP, is fragment navigation. Is pretty hard to make the navigation pretty in code. So i make my research and found some solicitous as using Event-buss, to post on one subscribed method in Activity i needed to open some fragment, or casting context to Activity's context, but always the code seems ugly and with MVP is even uglier.

So… one day testing an MVP framework i found on GitHub, i ended with a new idea of android fragment navigation that i really liked how it the code looks i enjoyed as well.

First i added an MainActivity with his presenter as sown in below:

MVP - Activity and his Presenter

The diagrams are made in PlantUML, with his AndoridStudioPlugin.

A pretty simple, basic MVP pattern with his code and stuff. The same for the fragments :

MVP Fragment and his Presenter

About the interfaces i like to keep them in another interface to group them easily:

public interface MainActivityVP {
interface View{
void setFragment(BaseFragment fragment);
}

interface Presenter{
void getRandomFragment();
}
}

This way is easier to find what you need.

Finally, let’s start with navigation, first i added a BaseFragment:

Then create a new interface for navigation:

Code below:

public interface FragmentNavigation {
interface View {
void atachPresenter(Presenter presenter);

}

interface Presenter {
void addFragment(BaseFragment fragment);
}
}

And now putting all together it looks something like this:

When i drew the diagram i thought that is complicated but in code is really easy.

In the BaseFragment set the implementation of the navigation method like:

public abstract class BaseFragment extends Fragment implements FragmentNavigation.View {


protected FragmentNavigation.Presenter navigationPresenter;

@Override
public void atachPresenter(
FragmentNavigation.Presenter presenter) {
navigationPresenter = presenter;
}

}

Then in the MainPresenter implement the Presenter navigation logic:

public class MainActivityPresenter implements            
MainActivityVP.Presenter,
FragmentNavigation.Presenter {
//...
    @Override
public void addFragment(BaseFragment fragment) {
view.setFragment(fragment);
}

}

In the main activity just implement the logic like below:

public class MainActivity extends AppCompatActivity implements MainActivityVP.View{

//...

@Override
public void setFragment(BaseFragment fragment) {
//ataching to fragment the navigation presenter
fragment.atachPresenter(presenter);
//showing the presenter on screen
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container,fragment)
.commit();

}
}

And that’s it, the hard part is gone, now just call the navigationPresenter and send in param field what fragment to show on screen:

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
navigationPresenter.addFragment(new FragmentTow());
}
});

Of course you can explore the code on GitHub if you want to understand this better or if i didn’t explained very well.