2014-05-02 9 views
5

Sto costruendo la mia app con Mortar + Flow. Sto cercando di capire il modo corretto per mostrare un popup che richiede del testo all'utente. Ho creato questa classe popup:Ottenere l'input dell'utente da una finestra di dialogo usando Mortar + Flow

public class SavedPageTitleInputPopup implements Popup<SavedPageTitleInput, Optional<String>> { 

private final Context context; 

private AlertDialog dialog; 

public SavedPageTitleInputPopup(Context context) { 
    this.context = context; 
} 

@Override public Context getContext() { 
    return context; 
} 

@Override 
public void show(final SavedPageTitleInput info, boolean withFlourish, 
       final PopupPresenter<SavedPageTitleInput, Optional<String>> presenter) { 
    if (dialog != null) throw new IllegalStateException("Already showing, can't show " + info); 

    final EditText input = new EditText(context); 
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 
                   LinearLayout.LayoutParams.MATCH_PARENT); 
    input.setLayoutParams(lp); 
    input.setText(info.savedPage.getName()); 

    dialog = new AlertDialog.Builder(context).setTitle(info.title) 
              .setView(input) 
              .setMessage(info.body) 
              .setPositiveButton(info.confirm, new DialogInterface.OnClickListener() { 
               @Override public void onClick(DialogInterface d, int which) { 
                dialog = null; 
                final String newTitle = Strings.emptyToNull(String.valueOf(input.getText())); 
                presenter.onDismissed(Optional.fromNullable(newTitle)); 
               } 
              }) 
              .setNegativeButton(info.cancel, new DialogInterface.OnClickListener() { 
               @Override public void onClick(DialogInterface d, int which) { 
                dialog = null; 
                presenter.onDismissed(Optional.<String>absent()); 
               } 
              }) 
              .setCancelable(true) 
              .setOnCancelListener(new DialogInterface.OnCancelListener() { 
               @Override public void onCancel(DialogInterface d) { 
                dialog = null; 
                presenter.onDismissed(Optional.<String>absent()); 
               } 
              }) 
              .show(); 
} 

@Override public boolean isShowing() { 
    return dialog != null; 
} 

@Override public void dismiss(boolean withFlourish) { 
    dialog.dismiss(); 
    dialog = null; 
} 
} 

Questa classe funziona come previsto. Utilizza lo SavedPage per capire cosa visualizzare nella finestra di dialogo e restituisce l'input dell'utente allo PopupPresenter utilizzando PopupPresenter#onDismissed quando viene premuto il pulsante corretto.

Il mio problema è scrivere la sottoclasse PopupPresenter utilizzata per presentare la finestra di dialogo ed elaborare l'input. Questo è quello che ho in questo momento:

new PopupPresenter<SavedPage, Optional<String>>() { 
    @Override protected void onPopupResult(Optional<String> result) { 
    if (result.isPresent()) { 
     // The user entered something, so update the API 
     // Oh wait, I don't have a reference to the SavedPage 
     // that was displayed in the dialog! 
    } 
    } 
} 

Come dicono i commenti, non ho un riferimento al SavedPage che è stato visualizzato nella finestra di dialogo. È stato memorizzato nel campo whatToShow in PopupPresenter, ma questo campo è annullato prima che venga chiamato lo onPopupResult. Sembra che mi stia ripetendo inutilmente per mantenere una copia aggiuntiva di SavedPage.

risposta

0

Non c'è ancora molta documentazione su PopupPresenter e Popup. L'unica cosa che ho visto è un esempio di base nel progetto di esempio. Creano un ConfirmerPopup in base ai dati nell'oggetto Confirmation. Lo scopo di ConfirmerPopup è quello di acquisire una decisione booleana da parte dell'utente in base al titolo/corpo assegnato all'oggetto Confirmation come visto dalla dichiarazione della classe.

public class ConfirmerPopup implements Popup<Confirmation, Boolean> { 

Nel tuo caso, vuoi catturare un testo immesso dall'utente aggiuntivo dall'utente. Quando viene chiamato PopupPresenter # onPopupResult, l'oggetto risultato deve contenere tutti i dati necessari da SavedPageTitleInputPopup. Modifica la tua SavedPageTitleInputPopup come segue

public class SavedPageTitleInputPopup implements Popup<SavedPage, SavedPageResults> { 
    private final Context context; 
    private AlertDialog dialog; 

    public SavedPageTitleInputPopup(Context context) { 
    this.context = context; 
    } 

    @Override public Context getContext() { 
    return context; 
    } 

    @Override 
    public void show(SavedPage info, boolean withFlourish, final PopupPresenter<SavedPage, SavedPageResults> presenter) { 
    if (dialog != null) throw new IllegalStateException("Already showing, can't show " + info); 
    // Create your Dialog but scrape all user data within OnClickListeners 
    final AlertDialog.Builder builder = new AlertDialog.Builder(context); 
    //Anything else you need to do... .setView() or .setTitle() for example 
    builder.setPositiveButton(info.confirm, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface d, int which) { 
     dialog = null; 
     //Save data to SavedPageResults 
     final SavedPageResults results = new SavedPageResults(): 
     presenter.onDismissed(results); 
     } 
    }); 
    builder.setNegativeButton(info.cancel, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface d, int which) { 
     dialog = null; 
     final SavedPageResults results = new SavedPageResults(); 
     presenter.onDismissed(results); 
     } 
    }); 
    dialog = builder.show(); 
    } 

    @Override public boolean isShowing() { 
    return dialog != null; 
    } 

    @Override public void dismiss(boolean withFlourish) { 
    dialog.dismiss(); 
    dialog = null; 
    } 
} 

tuo PopupPresenter non ha bisogno di sapere nulla di implementazione della finestra di dialogo ora.

new PopupPresenter<SavedPage, SavedPageResults>() { 
    @Override protected void onPopupResult(SavedPageResults result) { 
    if (result.isPresent()) { 
     updateUi(result.getSavedText()); 
    } 
    } 
} 
+0

Grazie per la risposta. Ho già visto l'esempio di 'ConfirmerPopup' e l'ho modificato in modo che la mia finestra di dialogo sia visualizzata come la voglio io. Come ho accennato nella domanda, il mio problema ha a che fare con il mantenere un riferimento al campo 'whatToShow' nel' PopupPresenter'. Non penso che tu abbia risposto a questo. –

+0

Non dovresti avere bisogno di un riferimento a 'whatToShow'. Di cosa hai bisogno per accedere a 'onPopupResult' che non puoi accedere a 'OnClickListener'? – Alex

+0

@ scompt.com se aggiorni la tua domanda con il tuo pieno 'SavedPageTitleInputPopup' e' popup.xml' ti mostrerò cosa intendo. – Alex

Problemi correlati