2016-04-28 17 views

risposta

24

Sì, è un anti-mvp-modello. Basato su passive view in MVP, hai perso la testabilità, perché non hai a che fare con il framework Android nel tuo presentatore.

Quindi è meglio gestire la navigazione dell'app dal View Layer.

class MyPresenter { 
    MyPresenter.View view; 

    void backButtonClicked() { 
     view.navigateToHomeScreen(); 
    } 

    public interface View { 
     void navigateToHomeScreen(); 
    } 
} 

class MyActivity extends Activity implements MyPresenter.View { 
    @Override 
    void navigateToHomeScreen() { 
     startActivity(...) 
    } 

    @OnClick(R.id.my_button) 
    void onClick() { 
     presenter.backButtonClicked(); 
    } 
} 

anche un altro vantaggio di questo modo è che sarà facile sostituire l'attività con un frammento o una vista.

Edit 1:

Morgwai detto in questo modo si romperà la separazione di preoccupazione e responsabilità single, ma non si può avere un'unica responsabilità in ogni dove. A volte devi violarlo. Ecco un esempio da Google per MVP:

TaskDetailPresenter chiamate ShowEditTask che è responsabile per aprire una nuova Activity all'interno TaskDetailFragment.

Ma è anche possibile utilizzare CommandPattern che è un approccio migliore

interface NavigationCommand { 
    void navigate(); 
} 

Quindi, Presentatore lo userà quando ha bisogno.

+1

E se mi piacerebbe passare alcuni dati tramite extra? Non violerà ancora il mvp? Perché la vista non dovrebbe sapere nulla dei modelli. – cylon

+0

IMO una vista dovrebbe contenere SOLO metodi per aggiornare la schermata dell'interfaccia utente corrente e la navigazione NON dovrebbe essere la responsabilità della vista in quanto interrompe la regola della separazione delle preoccupazioni. Nel classico MVP, il presentatore corrente decide a quale altro presentatore passare un controllo (di solito usando un bus dei messaggi), quindi il bersaglio mette la sua vista su una "tela". In Android la navigazione viene solitamente eseguita utilizzando un'attività o un oggetto frammento e, poiché le viste vengono solitamente implementate da un frammento o un'attività, anche gli oggetti vista vengono spesso utilizzati per eseguire anche la navigazione. Comunque è una chiara rottura della regola di separazione delle preoccupazioni IMO – morgwai

+0

Bene signore, avete un esempio di pattern MVP + Command Android da qualche parte @SaeedMasoumi? – ericn

4

A mio parere sarebbe meglio se si apre un'attività dal livello Visualizza. Preferisco che Presenter conosca l'attività il meno possibile.

Se c'è una certa condizione di ciò che dovrebbe essere avviato l'attività, è possibile utilizzare qualcosa di simile:

public class Presenter { 

    private ViewsPresentation mViewsPresentation; 

    public void someButtonClicked() { 
     if (/*some condition*/) { 
      mViewsPresentation.startFirstActivity(); 
     } else { 
      mViewsPresentation.startSecondActivity(); 
     } 
    } 

    public interface ViewsPresentation { 
     void startFirstActivity(); 
     void startSecondActivity(); 
    } 

} 
5

Come ho scritto nel mio commento allo accepted answer, penso che la gestione della navigazione dal livello di vista sia una chiara separazione della regola di separazione delle preoccupazioni: le viste dovrebbero contenere SOLO metodi per aggiornare la schermata dell'interfaccia utente corrente.

Il problema ha origine dal progetto della piattaforma Android come Activity e Fragment classi contengono entrambi i metodi per operare sullo schermo dell'interfaccia utente e per inviare oggetti intento che iniziano altre attività come startActivity.

Un modo semplice per risolvere questo problema consiste nel creare un'interfaccia Navigator che contenga metodi relativi alla navigazione, che le attività possano implementarla e iniettarla anche nei relatori. In questo modo, almeno dal punto di vista dei presentatori, la navigazione e la manipolazione dell'interfaccia utente sarebbero separate. Potrebbe tuttavia sembrare strano dal punto di vista delle attività: ora spesso implementerebbero entrambe le interfacce (Navigator e View) e passeranno il loro riferimento 2 volte al presentatore. Se, per questo motivo, decidi di gestire la navigazione dal livello di visualizzazione, mantieni almeno i metodi per navigare separatamente da quelli per la manipolazione dell'interfaccia utente: non eseguire mai la navigazione e la manipolazione dell'interfaccia utente con lo stesso metodo.

+0

Avete implementato progetti di esempio di questa interfaccia di Navigator? – toobsco42