C
C
CheY2015-06-18 21:56:32
Android
CheY, 2015-06-18 21:56:32

MVP in Android with a complex interface of several fragments. What is the best way to coordinate?

Hello.
I'm trying to master development for Android and after a couple of visits I always got bogged down in the spaghetti code of bloated activities and fragments. Therefore, I decided to apply best practices in terms of architecture, and more specifically MVP. In principle, the idea is beautiful and everything is implemented quite simply, but a fundamental question arose.
Suppose we have a two-pane application - for concreteness, let's take a map with markers and a list of these markers. Accordingly, there are two fragments: MyMapFragment and MyListFragment. In general, select, add, delete, click, and other events can be caught by any of them. The task is to coordinate the states of both displays: if we have selected a marker on the map, then we need to select it in the list, or if we changed the name of the marker in the list, then we need to immediately update it on the map.
Question: which way is the most correct?
I see three options:
1) All issues of coordination of views lies with the Presenter.
b1b8f57065f14d119bdc194f36e2fc39.png
Accordingly, immediately after instantiating the Presenter, we register each fragment in it as an implementation of interfaces for MarkersView callbacks. At the same time, an important point: the Presenter clearly knows which implementation refers to what and which implementation refers to it. In other words, in addition to the function of routing data from View to Model and vice versa, our Presenter is now also routing event notifications between Views known to it.
But as I understand it, this violates the MVP ideology in the sense that the Presenter now knows too much about views.
2) Presenter deals only with data routing, and view approvals are handled by a separate MarkersViewsMediator intermediary class.
e5b5a9de7d0445da83250d52553da8ad.png
In this case, the Presenter is blind and accepts events from any of the fragments and calls the callbacks of the fragment that accessed it. To negotiate their states, fragments use the MarkersViewMediator as a common bus to communicate updates to their states.
But here you can notice a potential problem - the Presenter does not know anything about the fragments registered in it (this is good), so it can either pull the callback of one fragment that has addressed it (it looks like the option when each fragment has its own copy of the presenter), or all at once (and here problems and bad code may already emerge).
3) As item 2, but Fragments communicate with Presenter only through an intermediary.
32197528868a4561b22e5213f401b46f.png
In other words, our mediator becomes the master view, coordinating the work of the fragments, sending events to the Presenter, and providing the implementation of the callbacks.
But the size of such a class can be impressive, and in general it must be fully aware of the fragments connected to it.
You can see that an activity containing these same fragments may be suitable for the role of such an intermediary. The truth will have to be closely tied to the events of its life cycle. Another option is a separate singleton.
Or maybe there is another better way?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
K
Konstantin, 2015-06-25
Kiriushyn @KonstantinKiriushyn

According to best practices , the interaction of two fragments is organized through the Activity that hosts them.
Among the proposed options, I like option 3 the most.
As part of the task, I would do Activity = MasterView, and I would communicate with the Presenter's Activity. Further Activity would serve as Mediator'om and a certain coordinator for fragments.
I propose to consider a scheme with two Presenters. The first is responsible for loading the list with a marker and works with MyListFragment, the second is for working with the map and is bound to MyMapFragment.
And the mediator is still an Activity with interfaces.
How will it work? (outer code omitted)

//MapInterface реализует Activity для взаимодействия между фрагментами.
mMapInterface.onMarkerSelected(marker);

public void onMarkerSelected(Marker marker) {
      mMapFragment.selectMarker(marker);
}

public void selectMarker(Marker marker) {
       //например грузим информацию по маркеру
      mMapPresenter.loadMarkerInfo(marker, someCallback).
      //или просто производим манипуляции со View.
}

If the operations performed with the Model are the same, then you can get by with one presenter, but it will still twitch from the Fragments. Because, since we are talking about good design, in case of further complicating the logic of Fragments, it is better that everyone hosts their own Presenter.
I am happy to discuss the topic.
Thank you!

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question