Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleMaps using rxJava with MVP

I've an app that from now I have a list filled up from my api. Now I'm detecting the onClick on recyclerView and I want to open a GoogleMaps with a marker focused on the item I clicked (I have lat and long). Is there a good approach to do this with it's Repository, usecases, model, etc?

The thing is that I have on my ModelView is the coordinates where it is, and the type of cat, also the id.

The thing is that I do not know what to send to the other activity because everytime I make an api call the data changes, so I do not know if I have to store it anywhere and then show the data from listView and then create a refresh button on mapActivity where I can restart the data from api.

Hope you understand my problem.

An example that I'm following is this one : GitHub repository this is what I have as a list, then when clicking on an item it should open the map.

EDIT

I ended up passing the list when I click on an item from the List (If you have any other way please feel free to tell me)

Then I created a contract that it's :

interface Presenter{
        fun onMapReady()
    }

    interface View{
        fun focusOnItem(latitude: Double, longitude: Double)
        fun putMarkers(mList)
    }

Then I do not know where to use rxJava on my presenter, because I need to wait until I set stuff for my presenter like views and data and when I filled all up then start doing the putMarkers first, then focusOnItem, but I'm stuck on this.

So what I'm doing at the moment is from mapActivity I set the list and then I want to start doing the job.

TL;DR

Since start I had an activity (that is almost the same from the Github repo and then I need to pass the list to my other activity I ended up doing a setter to a presenter because dagger didn't know about that list so, my problem now is how do I set up all of the MVP with rxJava to load the map and load the markers on it. It should also zoom to the element clicked but I already have the location.

With a simple pseudo if you convince myself to do it this way I'll accept your answer as a correct, I just need to figure it out how to do this in rxJava.

like image 737
StuartDTO Avatar asked Oct 28 '18 14:10

StuartDTO


1 Answers

You should not pass big amounts of data from one Activity to another, as you can easily reach the maximum amount that may be passed between them.

Instead, you should better save your data in your model classed for one Activity (for example, the one containing the list), and then pass only some item id to the other one. The second Activity (more precise, its presenter), should take the id and query the required object from the model.

Overall, the call chain will look like:

  1. Activity with list of items downloads this items when it is created. The download is initiated in ItemsListPresenter that calls Interactor/UseCase or directly a Repository.

  2. The downloaded items are cached in some way using the Repository.

  3. The downloaded items are displayed as a list in the View (in our case - Activity).
  4. When user clicks on item, this click is sent to ItemsListPresenter, and it sends a call to navigate to MapsView, passing the selected item id as a parameter.
  5. MapActivity is opened, the passed item id is taken.
  6. MapPresenter gets selected id in its constructor (or a setter)
  7. MapPresenter gets all the points from model (in our case using Interactor/UseCase or directly a Repository) and displays them.
  8. MapPresenter makes view to focus on a selected point (where the point is taken from model by its id)

As a result, we manage to open a screen that will contains all the points and it will be focused on the one selected by user.

You can find a simple Earthquakes app created based on the Clean Architecture approach and using MVP pattern and RxJava 2 here: https://github.com/Gaket/Earthquakes

Upd:

To be little more precise, you can do it like this (pseudocode):

class Presenter extends IPresenter {

   Model model;
   View view;
   List<Item> elements;
   Item selectedElement;

   void setSelectedItem(String id) {
      element = model.getElement(id);
   }

   void start() {
      // if you need to make an api call - do it here
      model.getElements().subscribe(elements -> this.elements = elements);
   }

   void onMapReady() {
      view.showElements(elements);
      view.focus(selectedElement);
   }
}

class MapActivity implements View {
    IPresenter presenter;

    void onCreate(...) {
        // start your map fragment
        String id = // get id from Intent
        presenter.setSelectedItem(id);
        presenter.start();
    }

    void putMarkers(List<Item> elements) {
        // put your markers as usual
    }

    void focusOnItem(Element element) {
        // and focus works the same. The only question is if you want to send an Element object here or particular coordinates. Both variants work.
    }

    @Override
    void onMapReady(GoogleMap map) {
         // save map
         presenter.onMapReady();
    }

}
like image 139
Gaket Avatar answered Oct 21 '22 02:10

Gaket