web-dev-qa-db-fra.com

Dans une action de casse-croûte, comment puis-je être sûr qu'il est sécuritaire de supprimer définitivement un enregistrement supprimé par logiciel de la base de données?

J'utilise Snackbar sous Android et j'ai implémenté une action afin que l'utilisateur puisse annuler l'action (l'action efface tous les éléments de la vue liste). La suppression et l'ajout des éléments à la liste ont déjà été effectués et fonctionnent correctement.

Mon problème est que les éléments sont stockés dans une base de données sqlite et comment puis-je les supprimer des tables? (Comment puis-je savoir que l'utilisateur n'a pas cliqué sur le bouton Annuler, afin de pouvoir supprimer complètement les données de la base de données).

C'est le code à l'intérieur de 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;

Donc, si l'utilisateur n'a pas cliqué sur le bouton Annuler au cours de la période visible du snack-bar, je dois alors supprimer définitivement les données de la base de données.

Des solutions pour cela?

16
chathura

Pour autant que je sache, c'est par conception. Vous devriez:

  • Supprimer l'élément dès que l'utilisateur appuie sur le bouton de suppression;
  • Stockez-le temporairement dans une variable de classe;
  • Si l'utilisateur appuie sur Annuler, rajoutez l'élément à la base de données.

Cette approche est plus sûre et plus robuste; vous ne devriez pas attendre que le snackbar soit congédié, car cela ne pourrait même pas arriver. Pensez simplement à l'utilisateur qui quitte l'application de force lorsque la barre est toujours allumée: cet élément doit-il être supprimé ou non? Cela devrait.

Cette source plus fiable est this g + post de Ian Lake. Dans les commentaires, vous pouvez lire:

vous voulez que votre interface réagisse immédiatement (n'attendez pas que le snackbar disparaisse) - la plupart des systèmes (en particulier ceux qui se synchronisent sur un serveur externe ) ont le concept de «suppression douce» sont marqués comme supprimé. Dans ces cas, une action d'annulation annulerait simplement la suppression de l'enregistrement . Ce système fonctionne même si l'utilisateur devait quitter L'application avant la fin du snack-bar (vous ne pouvez pas supposer que le snackbar complétera toujours son animation!).

Le moyen le plus simple de le faire est de sauvegarder temporairement l’enregistrement ailleurs (même une variable locale ), Puis de le réinsérer s’il arrive de cliquer sur le bouton Annuler.

23
natario

Bibliothèque de support Android v23 ajoutée Snackbar.Callback que vous pouvez utiliser pour écouter si le snack-bar a été congédié par l'utilisateur ou expiré.

Exemple emprunté à 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

Exemple:

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

Il peut être judicieux d’ajouter un peu de temps à snackbar.getDuration () (100-200ms?), Car les minuteries ne sont pas très précises en termes de timing et peuvent ainsi être appelées juste avant la fermeture du snack-bar Bien que la possibilité soit plutôt faible dans ce cas.

4
WFranczyk

Si vous ne souhaitez pas supprimer immédiatement l'enregistrement de la base de données, essayez ceci:

// 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