RecyclerView ItemTouchHelper getAdapterPosition()在快速滑动时返回错误的值

时间:2017-08-03 10:56:43

标签: android android-recyclerview android-snackbar snackbar itemtouchhelper

我有一个关于RecyclerView + Swipe的问题,以便在快餐栏的帮助下删除+撤消。每当我尝试快速滑动3个项目以删除它们时,viewHolder.getAdapterPosition();都会返回错误的值。似乎它无法快速做出反应。

RecyclerView列表示例:

  1. 测试1
  2. 的Test2
  3. Test3的
  4. TEST4
  5. 所以,如果我快速扫掉Test3,Test2然后Test1 viewHolder.getAdapterPosition();返回位置2,2,然后返回0。 正确的回报必须是2,1,然后是0。

    对于两个项目,一切都表现正常,返回2然后返回1.

    注意:最后一个位置总是在2秒后返回,因为小吃栏超时,然后该项目被删除。在下一个物品被擦掉之前,显示的小吃店会被解雇。

    任何想法如何解决这个问题? 我试着弄清楚几个小时了。

    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);
    

1 个答案:

答案 0 :(得分:1)

看起来你要从支持数据存储中删除该项,在你的情况下,它是arrayList并且仅在SnackBar解散后通知适配器。

因此,如果您在第一个Snackbar解散之前滑动下一个项目,则RecyclerView适配器不知道第一个项目已从适配器中删除。所以它给你一个错误的立场。

您应该从支持数据存储(arrayList)中删除该项目,并在刷卡项目时立即调用notifyItemRemoved(),而不是在Snackbar解除后更新。

但是,只有在SnackBar解散后才能更新数据库。