【问题标题】:Getting notified about item delete in RealmRecyclerView在 RealmRecyclerView 中获取有关项目删除的通知
【发布时间】:2016-07-08 16:12:28
【问题描述】:

我正在使用这篇文章中的 RealmRecyclerView:https://realm.io/news/android-realm-listview/ 在这个 ToDo 应用程序中,当项目被滑动时,它会自动从 RecyclerView 以及 Realm 数据库中删除。 我想在删除某个项目时收到通知,以及删除哪个项目,以便我可以对该项目执行一些操作。 我尝试使用领域更改侦听器,但每次提交领域事务时都会调用它。因此,即使添加了新项目,它也会被调用。 我该怎么做呢?普通的 RecyclerView 可以吗?

【问题讨论】:

    标签: android android-recyclerview realm


    【解决方案1】:

    目前(V1.1.0 版本),Realm 在删除 RealmObject 时不提供回调。这适用于所有类型的数据/视图(listView、RecyclerView、RealmObject、RealmResults 等),如果您将数据查询为 Observable 或使用更改侦听器,也是如此。

    但是发送一个空对象确实有意义,当查询的对象从 Realm 中删除时,但由于它在 Realm 中发生了重大变化,我们将不得不等待 V2.0。

    更多详情 - https://github.com/realm/realm-java/issues/3138

    【讨论】:

      【解决方案2】:
      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. 
      

      【讨论】:

        【解决方案3】:

        虽然 Realm 可能不会在删除项目时提供回调,但当使用来自 this postRealmRecyclerView 时,有一种方法可以知道项目何时被删除。

        适配器 (RealmBasedRecyclerViewAdapter) 将调用 onItemSwipedDismiss(int position) 每当滑动项目以关闭。在这个适配器的子类中,你可以重写这个方法来添加一些额外的逻辑。

        例如,在我的回收站视图中,我想为用户提供撤消删除的选项。所以,我覆盖onItemSwipedDismiss(int position) 并访问被删除对象的字段。 (在我的例子中,这个对象相当小——只有三个字段——所以这不是太笨拙)。然后我调用 super 方法:super.onItemSwipedDismiss(position);,它将动画删除并将其从 Realm 中删除。

        然后,我创建一个 Snackbar,其中包含一个从保存的字段重新创建 Realm 对象的操作。创建完成后,它会立即返回到回收站视图。

        这里是这个方法覆盖的实现框架:

        @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)
        }
        

        【讨论】:

          猜你喜欢
          • 2014-05-21
          • 2015-05-24
          • 2023-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-02
          • 2015-12-15
          相关资源
          最近更新 更多