2016-07-08 5 views
2

Ich benutze die RealmRecyclerView von diesem Beitrag: https://realm.io/news/android-realm-listview/ In dieser ToDo App, wenn Artikel überstrichen wird, wird es automatisch aus RecyclerView sowie Realm-Datenbank gelöscht. Ich möchte benachrichtigt werden, wenn ein Element gelöscht wird, auch welches Element gelöscht wird, damit ich eine Aktion mit diesem Element ausführen kann. Ich habe versucht, den Realm-Change-Listener zu verwenden, aber dieser wird jedes Mal aufgerufen, wenn eine Realm-Transaktion festgeschrieben wird. Es wird also aufgerufen, auch wenn ein neues Objekt hinzugefügt wird. Wie mache ich das? Ist es mit normalem RecyclerView möglich?Benachrichtigung über Artikel löschen in RealmRecyclerView

Antwort

1

Zu diesem Zeitpunkt (mit Version V1.1.0) bietet Realm keinen Rückruf, wenn ein RealmObject gelöscht wird. Dies gilt für alle Arten von Daten/Sichten (listView, RecyclerView, RealmObject, RealmResults usw.). Dies gilt auch, wenn Sie Daten alsObservable abfragen oder einen Änderungslistener verwenden.

Allerdings ist es sinnvoll, ein leeres Objekt zu senden, wenn das abgefragte Objekt aus Realm gelöscht wird, aber da es eine brechende Änderung in Realm ist, müssen wir auf V2.0 warten.

Weitere Details - https://github.com/realm/realm-java/issues/3138

1
According to the answer, they have not yet added this feature. But if you want to achieve this, you can use normal ReacyclerView using the existing RealmAdapter and everything as it is. 
Here's how to do it:- 

Remove the RealmRecyclerView and add the normal RecyclerView:- 

1. Add the normal RecyclerView from the support library. 

2. Initialize the recyclerview with the existing adapter i.e the adapter class that extends RealmBasedRecyclerViewAdapter, no need to make a new adapter  

     recyclerView=(RecyclerView)findViewById(R.id.realm_recyeler_view); 
     recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
     adapter = new FilterAdapter(this,results,true,true); 
     recyclerView.setAdapter(adapter); 

3. Next, we will use the ItemTouchHelper class to implement the swipe to dismiss for the RecyclerView :- 

      ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {    
      @Override 
      public boolean onMove(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)  { 
           return false; 
          } 

      @Override 
      public void onSwiped(RecyclerView.ViewHolder  viewHolder, int direction) { 
             adapter.remove(viewHolder.getAdapterPosition(),alarmintent); 
           } 
      }; 

I've made a method in my adapter to remove item(shown below), you can do it here as well 
The viewHolder.getAdapterPositon() gives the position of item swiped, it is passed to delete the RealmObject from Realm DB at given position(shown below) 
0 -> drag flag - since I am not implement drag to move items, I've kept it as zero 
ItemTouchHelper.RIGHT - swipe flags - These say in which direction the swipe to dismiss is set 
ItemTouchHelper.RIGHT - swipe in right direction to dismiss 
ItemTouchHelper.LEFT - swipe in left direction to dismiss 
To support both directions, pass- ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT 

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); 
       itemTouchHelper.attachToRecyclerView(recyclerView); 

Create a new ItemTouchHelper object with above callback 
Attach the ItemTouchHelper to RecyclerView 

4. Here's how to remove the item (below is the code of my remove method of adapter):- 

     public void remove(int position) 
     { 
      RealmConfiguration configuration = new RealmConfiguration.Builder(context).deleteRealmIfMigrationNeeded().build(); 
      realm = Realm.getInstance(configuration); 
      realm.beginTransaction(); 
      realmResults.deleteFromRealm(position); 
      realm.commitTransaction(); 
      notifyItemRemoved(position); 
     } 

deleteFromRealm method is used to delete item at given position 
call the notifyItemRemoved(position) to indicate item is removed at specified position 

5. That's it, very easy and no need to create new adapters etc. 
0

Während Realm kann nicht einen Rückruf für vorsehen, wenn ein Element gelöscht wird, gibt es eine Möglichkeit zu wissen, wenn Elemente gelöscht werden, wenn die RealmRecyclerView von this post verwenden.

Der Adapter (RealmBasedRecyclerViewAdapter) ruft onItemSwipedDismiss(int position) auf, wenn ein Element zur Entlassung kopiert wird. In Ihrer Unterklasse dieses Adapters können Sie diese Methode überschreiben, um zusätzliche Logik hinzuzufügen.

In meiner Recycler-Ansicht möchte ich beispielsweise Benutzern die Möglichkeit geben, einen Löschvorgang rückgängig zu machen. Also überschreibe ich onItemSwipedDismiss(int position) und greife auf die Felder des zu löschenden Objekts zu. (In meinem Fall ist dieses Objekt ziemlich klein - nur drei Felder - das ist also nicht zu sperrig). Dann rufe ich die Super-Methode super.onItemSwipedDismiss(position); auf, die den Löschvorgang animiert und aus Realm entfernt.

Dann erstelle ich eine Snackbar mit einer Aktion, die das Realm-Objekt aus den gespeicherten Feldern neu erstellt. Sobald es erstellt wurde, geht es sofort zurück in die Recycler-Ansicht.

Hier ist ein Skelett der Implementierung dieser Methode überschreiben:

@Override 
public void onItemSwipedDismiss(int position) { 
    // Gather the object's fields, if you want: 
    YourObject objectToDelete = realmResults.get(position); 

    final String title = objectToDelete.getTitle(); 
    final long timestamp = objectToDelete.timestamp; 

    // Perform delete and animation: 
    super.onItemSwipedDismiss(position); 

    // Add code here depending on what you want to do 
    // (for example, you could add a Snackbar that undoes 
    // the deletion by "resurrecting" your deleted object) 
}