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
Is this approach in any way violating the MVP methodology
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) ?
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.