web-dev-qa-db-de.com

Wie kann ich bei einer Snackbar-Aktion sicher sein, dass ein vorläufig gelöschter Datensatz dauerhaft aus der Datenbank gelöscht werden kann?

Ich verwende Snackbar in Android und habe eine Aktion implementiert, damit der Benutzer die Aktion rückgängig machen kann (die Aktion löscht alle Elemente in der Listenansicht). Das Entfernen und Hinzufügen der Elemente zur Listenansicht wurde bereits durchgeführt und funktioniert einwandfrei.

Mein Problem ist, dass Elemente in der SQLite-Datenbank gespeichert werden und wie kann ich die Elemente aus Tabellen löschen? (Woher weiß ich, dass der Benutzer nicht auf die Schaltfläche zum Rückgängigmachen geklickt hat, damit ich die Daten vollständig aus der Datenbank entfernen kann).

Dies ist der Code in 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;

Wenn der Benutzer während des sichtbaren Zeitraums der Snackbar nicht auf die Schaltfläche zum Rückgängigmachen geklickt hat, muss ich die Daten dauerhaft aus der Datenbank löschen.

Irgendwelche Lösungen dafür?

16
chathura

Soweit ich weiß, ist es beabsichtigt. Du solltest:

  • Löschen Sie das Element, sobald der Benutzer auf die Schaltfläche "Löschen" tippt.
  • Speichern Sie es temporär in einer Klassenvariablen.
  • Wenn der Benutzer auf Rückgängig tippt, fügen Sie das Element erneut zur Datenbank hinzu.

Dieser Ansatz ist sicherer und robuster. Sie sollten nicht warten, bis die Snackbar abgewiesen wird, da diese Aktion nicht einmal passieren kann. Denken Sie nur an einen Benutzer, der die App zwangsweise beendet, während die Snackbar noch eingeschaltet ist: Soll der Artikel gelöscht werden oder nicht? Es sollte.

Eine vertrauenswürdigere Quelle ist this g + post von Ian Lake. In den Kommentaren kannst du lesen:

sie möchten, dass Ihre Benutzeroberfläche sofort reagiert (nicht warten, bis die Snackbar verschwindet) - die meisten Systeme (insbesondere diejenigen, die mit einem externen -Server synchronisieren) haben das Konzept eines "weichen Löschens", wo sich Dinge befinden werden als gelöscht. In diesen Fällen würde eine Rückgängig-Aktion den -Datensatz nur als gelöscht markieren. Dieses System funktioniert auch, wenn der Benutzer Die App verlassen hat, bevor die Snackbar beendet ist (Sie können nicht davon ausgehen, dass die Snackbar Ihre Animation immer komplettiert!).

Am einfachsten können Sie dies tun, indem Sie den Datensatz vorübergehend an anderer Stelle speichern (sogar eine lokale Variable ) Und ihn dann erneut einfügen, wenn er die Rückgängig-Schaltfläche drückt.

23
natario

Android Support-Bibliothek v23 hinzugefügt Snackbar.Callback , die Sie verwenden können, um zu hören, ob die Snackbar vom Benutzer abgelehnt wurde oder das Zeitlimit überschritten wurde.

Beispiel aus astinx s Post:

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();
7
Irritator

Beispiel:

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());

Es ist möglicherweise eine gute Idee, der snackbar etwas hinzuzufügen. GetDuration () time (100-200ms?), Da die Timer nicht sehr genau sind und auf diese Weise kurz vor dem Schließen der snackbar gerufen werden. Obwohl die Möglichkeit in diesem Fall eher gering ist.

4
WFranczyk

Wenn Sie den Datensatz nicht sofort aus der Datenbank löschen möchten, versuchen Sie Folgendes:

// Backup the item for undo
int itemIndex = viewHolder.getAdapterPosition();
Item item = adapter.getItem(itemIndex);

// Delete only from the adapter
adapter.removeItem(itemIndex);

Snackbar.make(getView(), "Item deleted", LENGTH_LONG)
        .addCallback(new BaseCallback<Snackbar>() {
            public void onDismissed(Snackbar transientBottomBar, int event) {
                if (event != DISMISS_EVENT_ACTION) {
                    // Dismiss wasn't because of tapping "UNDO"
                    // so here delete the item from databse
                }
            }
        })
        .setAction("UNDO", v -> adapter.addItem(item, itemIndex))
        .show();
0
Mahozad

Mein Weg ist es, eine "gelöschte" Spalte zu erstellen, die boolesch ist. Ändere einfach den Wert von stat auf true, wenn sie gelöscht wird, und mache ihn dann rückgängig, um stat auf false zu setzen.

0
Vampire