我有一个简单的RecyclerView用于显示项目。目前,我可以使用以下内容从RecyclerView.Adapter
成功删除项目。
private void removeItem(int pos) {
filteredDataSet.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, getItemCount());
}
我从onClick()
中的ViewHolder
函数调用它。动画有效,视图更新,一切正常。相当标准的RecyclerView。
但是,我想要做的是让用户通过Dialog
验证项目删除。这是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);
}
});
...
所以,我只是将方法调用移到Dialog的onClickListener
。
我遇到的问题是,当RecyclerView动画移除被移除的项目时,它会将其动画回到完全相同的位置,并且列表保持不变。就像它还在那里一样。
但是,如果我向下滚动,我会收到一个越界错误:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position
这意味着它实际上并不存在,当它再次回到View中时,它就消失了。因此,它似乎是缓存而不是更新适配器或数据集。我读到它需要在主线程上调用,所以我修改了我的方法:
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 :(得分:1)
通过使用回调来在从数据库中删除项目时触发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();
}
答案 1 :(得分:0)
如果您从onClick
班级ViewHolder
移除,请使用getAdapterPosition()
获取点击位置
如果此代码无效,您可以告诉onItemClick()
ViewHolder
的内容