2017-02-14 77 views
3

我有一个简单的RecyclerView显示项目。目前,从RecyclerView.Adapter,我可以使用以下方法成功删除项目。从对话框中删除RecyclerView项目不更新

private void removeItem(int pos) {  
    filteredDataSet.remove(pos); 
    notifyItemRemoved(pos); 
    notifyItemRangeChanged(pos, getItemCount()); 
} 

我把它从ViewHolder .The动画的onClick()功能正常工作,该视图更新,一切正常。非常标准的RecyclerView。

但是,我想要做的是让用户通过Dialog验证项目删除。下面是该对话框的基本设置(如果去掉不必要的代码):

... 

AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext()); 
builder.setTitle("Delete this item?"); 
builder.setView(layout); 

final int itemPos = pos; 

builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
     removeItem(itemPos); 
    } 
}); 

... 

所以,我只是移动的方法调用到对话框的onClickListener

我遇到的问题是,当RecyclerView消除已删除的项目时,它将其动画返回到完全相同的位置,并且列表保持不变。就像它仍然在那里。

但是,如果我向下滚动,我得到一个出界错误:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position

这意味着它实际上并不存在,而当回头进入查看一遍,就不见了。所以,它好像被缓存了,而不是更新适配器或数据集。我读出它需要所谓的主线程上,所以我修改了我的方法是:

private void removeItem(int pos) { 
final int itemPos = pos; 

Handler handler = new Handler(Looper.getMainLooper()); 
Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     filteredDataSet.remove(itemPos); 
     notifyItemRemoved(itemPos); 
     notifyItemRangeChanged(itemPos, getItemCount()); 
    } 
}; 
handler.post(runnable); 
} 

它仍然没有工作,我不知所措。我怀疑这是一个线程问题,但不知道从哪里开始。

+0

尝试调制。代码是正确的从列表中删除位置。 我认为问题是你从哪里调用removeItem方法的按钮的onclick事件,这里只是检查你是否传递正确的项目位置? –

+0

什么是filteredDataSet?它有什么价值? –

+0

@ keyur9779:传递的位置是正确的。 @quick学习者:filteredDataSet是通过SQL数据库填充的'List <>'。它按照需要运行(当然,减去提到的问题)。 – anthony

回答

1

这个问题onItemClick()通过使用回调解决当从数据库中删除项目时触发removeItem()函数。显然,在从数据库中实际删除项目之前,适配器正在被通知。

我正在使用DBFlow执行查询,因此该解决方案仅适用于基于DBFlow的解决方案。这是从持有RecyclerView的视图中调用的:

public void deleteItem(int pos, long id) { 
    DatabaseDefinition database = FlowManager.getDatabase(AppDatabase.class); 

    //hold id to remove later 
    final long tempId = id; 
    final int tempPos = pos; 

    final ItemModel currentItem = getItem(id); 

    Transaction transaction = database.beginTransactionAsync(new ITransaction() { 
     @Override 
     public void execute(DatabaseWrapper databaseWrapper) { 
      currentItem.delete(); 
     } 
    }).success(new Transaction.Success() { 
     @Override 
     public void onSuccess(Transaction transaction) { 
      mAdapter.removeItem(tempPos); //called here 
     } 
    }).error(new Transaction.Error() { 
     @Override 
     public void onError(Transaction transaction, Throwable error) { 
      Log.d("delete error", "item not deleted"); 
     } 
    }).build(); 

    transaction.execute(); 
} 
0

如果您从onClickViewHolder类删除,然后使用getAdapterPosition()获得点击的位置

如果这个代码不工作,你能告诉什么是你ViewHolder

+0

对不起,'onItemClick'是一个最初由'onClick'调用的接口方法。适配器位置通过位置参数在'onBindViewHolder(holder,position)'中设置。在今天上午进行了一些研究之后,我怀疑我可能需要使用'getAdapterPostition()',就像你所建议的那样,点击事件。 – anthony

+0

@anthony是否帮助我的解决方案 –

+0

直到今晚才能再次访问此项目,如果有问题,我会将其标记为已接受。谢谢。 – anthony