RecyclerView ItemTouchHelper getAdapterPosition() returns 快速滑动时的错误值
RecyclerView ItemTouchHelper getAdapterPosition() returns wrong value on fast swipe
我对 RecyclerView + 滑动删除 + 借助小吃栏撤消有疑问。每当我尝试快速滑动 3 个以上的项目以删除它们时,viewHolder.getAdapterPosition();
return 是一个错误的值。好像没反应那么快
RecyclerView 列表示例:
- 测试 1
- 测试2
- 测试3
- 测试4
所以,如果我快速滑开 Test3、Test2,然后是 Test1 viewHolder.getAdapterPosition();
returns 位置 2、2,然后是 0。
正确的 return 必须是 2、1 然后是 0。
对于两个项目,一切都正常,return先是 2,然后是 1。
注意:最后一个位置总是 return2 秒后编辑,因为 snackbar 超时然后项目被删除。之前显示的快餐栏会在下一项被滑走后立即消失。
有什么解决办法吗?
我试了好几个小时才弄明白。
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int swipeDir) {
final int position = viewHolder.getAdapterPosition();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
rusure = Snackbar.make(fab, getResources().getString(R.string.rule_deleted), Snackbar.LENGTH_SHORT).addCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar snackbar, int event) {
switch(event) {
case Snackbar.Callback.DISMISS_EVENT_ACTION:
rulesAdapter.notifyDataSetChanged();
break;
case Snackbar.Callback.DISMISS_EVENT_TIMEOUT:
case Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE:
case Snackbar.Callback.DISMISS_EVENT_MANUAL:
Log.d("test", Integer.toString(position));
if(position!=-1 && position<arrayList.size()){
// Define 'where' part of query.
String selection = DatabaseTablesColums.FeedEntry._ID + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = {Integer.toString(arrayList.get(position).getId())};
// Issue SQL statement.
arrayList.remove(position);
rulesAdapter.notifyItemRemoved(position);
rulesAdapter.notifyItemRangeChanged(position, rulesAdapter.getItemCount());
db.delete(DatabaseTablesColums.FeedEntry.TABLE_NAME, selection, selectionArgs);
// Remove item from backing list here
}
break;
}
}
@Override
public void onShown(Snackbar snackbar) {
}
}).setAction(getResources().getString(R.string.undo), new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
rusure.show();
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);
看起来您正在从后备数据存储中删除该项目,在您的情况下,它是 arrayList
并仅在 SnackBar 关闭后通知适配器。
因此,如果您在第一个 Snackbar 关闭之前滑动下一个项目,RecyclerView 适配器不知道第一个项目已从适配器中删除。所以它给了你一个错误的位置。
您应该从后备数据存储 (arrayList) 中删除该项目,并在滑动该项目后立即调用 notifyItemRemoved()
,而不是在 Snackbar 关闭后进行更新。
不过,您只能在 SnackBar 关闭后更新数据库。
我对 RecyclerView + 滑动删除 + 借助小吃栏撤消有疑问。每当我尝试快速滑动 3 个以上的项目以删除它们时,viewHolder.getAdapterPosition();
return 是一个错误的值。好像没反应那么快
RecyclerView 列表示例:
- 测试 1
- 测试2
- 测试3
- 测试4
所以,如果我快速滑开 Test3、Test2,然后是 Test1 viewHolder.getAdapterPosition();
returns 位置 2、2,然后是 0。
正确的 return 必须是 2、1 然后是 0。
对于两个项目,一切都正常,return先是 2,然后是 1。
注意:最后一个位置总是 return2 秒后编辑,因为 snackbar 超时然后项目被删除。之前显示的快餐栏会在下一项被滑走后立即消失。
有什么解决办法吗? 我试了好几个小时才弄明白。
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int swipeDir) {
final int position = viewHolder.getAdapterPosition();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
rusure = Snackbar.make(fab, getResources().getString(R.string.rule_deleted), Snackbar.LENGTH_SHORT).addCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar snackbar, int event) {
switch(event) {
case Snackbar.Callback.DISMISS_EVENT_ACTION:
rulesAdapter.notifyDataSetChanged();
break;
case Snackbar.Callback.DISMISS_EVENT_TIMEOUT:
case Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE:
case Snackbar.Callback.DISMISS_EVENT_MANUAL:
Log.d("test", Integer.toString(position));
if(position!=-1 && position<arrayList.size()){
// Define 'where' part of query.
String selection = DatabaseTablesColums.FeedEntry._ID + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = {Integer.toString(arrayList.get(position).getId())};
// Issue SQL statement.
arrayList.remove(position);
rulesAdapter.notifyItemRemoved(position);
rulesAdapter.notifyItemRangeChanged(position, rulesAdapter.getItemCount());
db.delete(DatabaseTablesColums.FeedEntry.TABLE_NAME, selection, selectionArgs);
// Remove item from backing list here
}
break;
}
}
@Override
public void onShown(Snackbar snackbar) {
}
}).setAction(getResources().getString(R.string.undo), new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
rusure.show();
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);
看起来您正在从后备数据存储中删除该项目,在您的情况下,它是 arrayList
并仅在 SnackBar 关闭后通知适配器。
因此,如果您在第一个 Snackbar 关闭之前滑动下一个项目,RecyclerView 适配器不知道第一个项目已从适配器中删除。所以它给了你一个错误的位置。
您应该从后备数据存储 (arrayList) 中删除该项目,并在滑动该项目后立即调用 notifyItemRemoved()
,而不是在 Snackbar 关闭后进行更新。
不过,您只能在 SnackBar 关闭后更新数据库。