13

Sto usando Snackbar in Android e ho implementato un'azione in modo che l'utente possa annullare l'azione (l'azione sta cancellando tutti gli elementi in listview). Rimuovendo e aggiungendo gli articoli nuovamente a listview è già stato fatto e lavorando bene .In un'azione snackbar, come posso essere sicuro che sia sicuro eliminare definitivamente un record cancellato dal database?

Il mio problema è che gli elementi sono memorizzati nel database SQLite e come posso eliminare gli articoli dalle tabelle? (Come posso sapere che l'utente non ha fatto clic sul pulsante Annulla, in modo da poter rimuovere completamente i dati dal database).

Questo è il codice all'interno OnOptionsItemSelcted()

case R.id.action_clear: 
     final List<Word> temp = new ArrayList<Word>(data); 
     data.clear(); 
     adapter.notifyDataSetChanged(); 
     View view = findViewById(R.id.layoutFavWords); 
     Snackbar.make(view,"Deleted Saved Selection.", Snackbar.LENGTH_LONG). 
     setAction("Undo", new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       for(Word word:temp) 
        data.add(word); 
       adapter.notifyDataSetChanged(); 
      } 

     }).show(); 
     break; 

Quindi, se l'utente non ha fatto clic sul pulsante Annulla durante il periodo visibile della snack bar, poi ho bisogno di eliminare definitivamente i dati dal database .

Qualche soluzione per questo?

+0

cancellare immediatamente e reinserirle se la stampa su undo? – Blackbelt

+0

sì, è un'altra opzione. Ma c'è un modo per ottenere ciò che voglio fare ?? cancella solo se l'utente non ha cliccato su Annulla bnn – chathura

+1

è abbastanza buono. Presumi che l'utente sappia ciò che vuole ma può cambiare idea (annulla). O probabilmente vuoi uno snackbar 'confirm-like'. Guardando la documentazione non sembra molto più di un Toast – Blackbelt

risposta

19

Per quanto ne so, è di progettazione. Si dovrebbe:

  • Elimina l'elemento non appena l'utente tocca il pulsante Elimina;
  • Memorizzarlo temporaneamente in una variabile di classe;
  • Se l'utente tocca Annulla, aggiungere nuovamente l'elemento al database.

Questo approccio è più sicuro e più robusto; non dovresti aspettare che lo snackbar venga licenziato, perché quell'azione non potrebbe nemmeno accadere. Basti pensare all'utente che chiude la app quando la barra degli snack è ancora attiva: l'elemento deve essere eliminato o no? Dovrebbe.

Una fonte più affidabile è this g+ post di Ian Lake. Nei commenti si può leggere:

si desidera l'interfaccia utente di reagire immediatamente (non attendere il rilascio del snack a scomparire) - la maggior parte dei sistemi (in particolare quelli che si sincronizzano con un server esterno ) avere il concetto di ' soft delete 'dove le cose sono contrassegnate come cancellate. In questi casi, un'azione di annullamento semplicemente annullerebbe la marcatura del record come eliminato. Questo sistema funziona anche se l'utente lasciava l'app prima che lo snack bar finisse (non si può supporre che lo snack bar completerà sempre la sua animazione!).

Il modo più semplice per farlo è quello di salvare temporaneamente il record altrove (anche una variabile locale ), quindi reinserirlo se succede di premere il pulsante Annulla.

+1

In caso di chiusura forzata, cosa succede se l'utente ha voluto annullare? È meglio avere i dati in caso di errore, perché l'utente che cancella di nuovo è solo a un tocco, ma la creazione dei dati non sarà relativamente facile, e in alcuni casi impossibile ad es. nel caso dei dati che hanno una lettura del sensore. Certo, l'interfaccia utente dovrebbe reagire immediatamente, come nel mio caso, ho due collezioni, una per gli articoli e una per il cestino. Quindi l'oggetto viene spostato nel cestino. Gli aggiornamenti del DB vengono eseguiti in un secondo momento e l'interfaccia utente funziona in modo silenzioso rispetto all'operazione DB a ogni modifica. – jasxir

+0

Contrassegna per l'eliminazione, esegui un'attività di pulizia extra all'avvio dell'app per ripulire eventuali record persistenti che potrebbero essere scivolati attraverso le fessure (ovvero non sono stati ripuliti quando Snackbar è stato chiuso) .. o anche ripristinare il loro flag di cancellazione. In questo modo hai anche la possibilità, ad esempio, di fornire all'Utente un'altra possibilità di annullare ... niente di peggio che cancellare accidentalmente qualcosa e mancare il pulsante Annulla prima che l'app venga uccisa/il telefono muore/incrinature dello schermo. – straya

4

Esempio:

final java.util.Timer timer = new Timer(); 
Snackbar snackbar = Snackbar.make(...).setAction("Undo", new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      timer.cancel(); 
      for(Word word:temp) 
       data.add(word); 
      adapter.notifyDataSetChanged(); 
     } 
    }).show(); 
timer.schedule(new TimerTask() { 
    public void run() { 
     // delete from db 
    } 
}, snackbar.getDuration()); 

Può essere una buona idea per aggiungere un po 'a snackbar.getDuration() Tempo (100-200ms?) Come timer non sono molto precisi in termini di tempi e in questo modo possono essere chiamati appena prima che lo snack bar stia per chiudersi, anche se in questo caso la possibilità è piuttosto piccola.

7

Libreria di supporto Android v23 aggiunto Snackbar.Callback che è possibile utilizzare per ascoltare se lo snackbar è stato chiuso dall'utente o timeout.

Esempio preso in prestito da astinx s postale:

Snackbar.make(getView(), "Hi there!", Snackbar.LENGTH_LONG).setCallback(new Snackbar.Callback() { 
      @Override 
      public void onDismissed(Snackbar snackbar, int event) { 
       switch(event) { 
        case Snackbar.Callback.DISMISS_EVENT_ACTION: 
         Toast.makeText(getActivity(), "Clicked the action", Toast.LENGTH_LONG).show(); 
         break; 
        case Snackbar.Callback.DISMISS_EVENT_TIMEOUT: 
         Toast.makeText(getActivity(), "Time out", Toast.LENGTH_LONG).show(); 
         break; 
       } 
      } 

      @Override 
      public void onShown(Snackbar snackbar) { 
       Toast.makeText(getActivity(), "This is my annoying step-brother", Toast.LENGTH_LONG).show(); 
      } 
     }).setAction("Go away!", new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

      } 
     }).show(); 
+0

Non dovrebbe il "Vai via" onClick contenere una chiamata a respingere()? – Radu

+0

Snackbars Il metodo setAction() gestisce la chiusura della barra snack in modo da non doverla fare da soli. – Irritator