使用Snackbar.Callback进行撤消删除操作

时间:2016-01-24 01:45:34

标签: android android-fragments android-recyclerview

我有一个工作线性RecyclerView,可以通过滑动删除,一切都很好。 但是,当我尝试Snackbar.Callback来创建"撤消"动作,我得到列表错误"无效索引",项目被刷掉然后立即重新出现,甚至"检测到不一致"错误。任何人都会在代码中看到奇怪的东西吗?

        @Override
        public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
            // item position
            final int pos = viewHolder.getAdapterPosition();
            communicator.remove(pos);
            recyclerViewAdapter.notifyItemRemoved(pos);

            Snackbar.make(view, R.string.notice_removed, Snackbar.LENGTH_LONG)
                    .setCallback(new Snackbar.Callback() {
                        @Override
                        public void onDismissed(Snackbar snackbar, int event) {
                            switch (event) {
                                case Snackbar.Callback.DISMISS_EVENT_ACTION:
                                     recyclerViewAdapter.notifyItemInserted(pos);
                                     break;
                                default:
                                    communicator.remove(pos);
                                    break;
                            }
                        }
                    })
                    .setAction(R.string.action_undo, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            // do nothing
                        }
                    })
                    .show();

            recyclerViewAdapter.notifyItemRangeChanged(pos, recyclerViewAdapter.getItemCount());
        }

1 个答案:

答案 0 :(得分:2)

使用final int pos = viewHolder.getAdapterPosition()并不是一个好主意。因为最终原因pos包含您在SnackBar CallBack侦听器中需要的错误索引。您可以使用view.getTagview.setTag来保存适配器位置的正确索引。也许这可以帮到你:

    @Override
    public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
        // hold position in view item
        int pos = viewHolder.getAdapterPosition();
        view.setTag(pos);
        communicator.remove(pos);
        recyclerViewAdapter.notifyItemRemoved(pos);
        //Snackbar.make(view, R.string.notice_removed, Snackbar.LENGTH_SHORT).show();
        Snackbar.make(view, R.string.notice_removed, Snackbar.LENGTH_LONG)
                .setCallback(new Snackbar.Callback() {
                    @Override
                    public void onDismissed(Snackbar snackbar, int event) {
                        //get position from view item of snackbar that you set it before.
                        int position = (int)snackbar.getView().getTag();
                        switch (event) {
                            case Snackbar.Callback.DISMISS_EVENT_ACTION:
                                 recyclerViewAdapter.notifyItemInserted(position);
                                 break;
                            default:
                                communicator.remove(position);
                                break;
                        }
                    }
                })
                .setAction(R.string.action_undo, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // do nothing
                    }
                })
                .show();

        recyclerViewAdapter.notifyItemRangeChanged(pos, recyclerViewAdapter.getItemCount());
    }