In MVP is onClick responsibility of View or Presenter?

Jim picture Jim · Jul 13, 2016 · Viewed 9k times · Source

In the MVP pattern who is responsible to handle clicks on the UI?
E.g. the non-MVP approach would be something like:

counterButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
      totalClicks++;
      counterTextView.setText("Total clicks so far: "+totalClicks);
    }
  });

Using MVP is the onClick the responsibility of the Presenter? Or the View can handle that?
Can someone please clarify this?

Answer

savepopulation picture savepopulation · Jul 13, 2016

OnClick should call a Presenter method. You should do your business in presenter and if you need to update the ui you should define a method in your View and call it from presenter.

You need a method for your View ex:

public void showCounterCount(final int totalClicks){
     counterTextView.setText("Total clicks so far: "+totalClicks);
}

Also you need a method and a variable in your Presenter:

int totalClicks = 0;

public void onCounterButtonClicked(){
    totalClicks++;
    mView.showCounterCount(totalClicks);
}

And refactor your code like this:

counterButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
      mPresenter.onCounterButtonClicked();
    }
  });

For more complex and clean architecture you can do your use case business in interactors. (In your example incrementing a counter value is a use-case for your application)

You can define an interactor and increment your counter value there.

CounterInteractor:

public CounterInteractor{
   public int incrementCounter(int currentCounter){
       return currentCounter+1;
   }
}

And refactor your presenter like below:

int totalClicks = 0;
CounterInteractor mCounterInteractor = new CounterInteractor();

public void onCounterButtonClicked(){
    totalClicks = mCounterInteractor.incrementCounter(totalClicks);
    mView.showCounterCount(totalClicks);
}

With this approach you separate your business logic totally from presenters and re use your use-case concepts without duplicating code in presenters. This is more clean approach.

You can also check this git repo for different MVP Approaches. https://github.com/googlesamples/android-architecture/tree/todo-mvp-clean/

Good luck.

Edit:

Here's my lightweight wikipedia client project source: https://github.com/savepopulation/wikilight

I'm trying to implement MVP. (MVP + Dagger2 + RxJava)