Search code examples
javaandroidmvpandroid-mvpclean-architecture

Presenter Instructing Current Activity to Inflate Next Activity; Violation of MVP Rules or Not


Considering the fact that in Android, you need a package context to be able to inflate the next activity from the current activity using an intent. However, with the MVP, the presenter is meant to be a pure Java class that is not glued to dependencies like the Android framework itself.

Is it proper to implement two methods in the view; One that asks the presenter to show a new view showNew(IView activity) and then the presenter authorizes this request by passing the new view back to the current view and asking it to use its (activity) context to inflate the requested next view.

In other words, the presenter is still the one who orders the creation of the next view, just that it does it through the context of the current view.

See Sample Code below:

View Interface

public interface IBaseView{
    void showAnother(Class nextActivity);
}

Presenter Interface

 public interface IBasePresenter {
      void showNew(IBaseView nextActivity);
}

Concrete Presenter

public class Presenter implements IBasePresenter {

IBaseView view;

public Presenter(IBaseView view){
    this.view = view;
}

@Override
public void showNew(IBaseView nextActivity) {
    view.showAnother(nextActivity.getClass());
}

Android Activity

public class SampleActivity extends AppCompatActivity implements IBaseView{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sample);
}

public void onClick(View view){
    Presenter presenter = new Presenter(this);
    presenter.showNew(new SampleNextActivity());
}

@Override
public void showAnother(Class nextActivity) {
    Intent intent = new Intent(this, nextActivity);
    startActivity(intent);
}

}

Android Next Activity

public class SampleNextActivity extends AppCompatActivity implements IBaseView {
    //activity details here
}

In Summary

View creates the next view, but only at the instruction of the presenter. Because the presenter needs the context of the current view to be able to inflate a next view.

Question

  1. Is this approach in any way violating the MVP methodology

  2. If (1) is a violation or not clean enough, is there a better way to make the presenter create the views (without having knowledge of the Android Context Class) ?


Solution

  • In MVP pattern, persenter tells view what to do. The way you are passing the next activity class to the presenter, and then presenter send that activity class back to view is unnecessary IMO. Why not the presenter tells the view to navigate to which activity without knowing the activity class itself? I mean something like this:

    Android Activity

    public class SampleActivity extends AppCompatActivity implements ISampleView {
    
        // ...
    
        public void onClick(View view){
            ISamplePresenter presenter = new SamplePresenter(this);
            presenter.buttonClicked();
        }
    
        @override
        public void navigateToNextView() {
            Intent intent = new Intent(this, nextActivity);
            startActivity(intent);
        }
    
    }
    

    Concrete Presenter

    public class SamplePresenter implements ISamplePresenter {
    
        ISampleView view;
    
        public Presenter(ISampleView view){
            this.view = view;
        }
    
        @Override
        public void buttonClicked() {
            // check if user can go to next activity
            view.navigateToNextView();
        }
    }
    

    You can have a method in your view which its job is to navigate to a specific view, i.e. NextActivity. If you have more acitivities, you can define a method for each one. When user clicks on a button, you tell the presenter that user clicked on a button. Then you can perform some logical operation after button is clicked in SamplePresenter#buttonClicked() and then tell the view to navigate to the NextAcitivity. This approach is cleaner in my opinion since you do not need to pass activity class itself to presenter.