当前位置: 首页 > 知识库问答 >
问题:

撤消后,Recycleview项不可见

怀展
2023-03-14

我是一个android编程新手,在我的应用程序中,我使用recycleview来显示SQLite数据库的内容,我将数据库读入一个Arraylist,我在recycleview中显示它。我已经成功实现了向左滑动(删除项目)和向右滑动(编辑项目)功能。我在向左滑动时遇到了一个问题,这意味着在删除功能中,我实现了一个撤销功能:

    void restoreItem( SequenceItem sequenceItem, int position) {
    sequenceItemList.add(position, sequenceItem);
    notifyItemInserted(position);
    notifyItemRangeChanged(position, getItemCount());
    }

(SequenceItem 是我的自定义项类,sequenceItemList 是我的 arraylist)

如果我删除了第一个或最后一个项目之间的列表项目并撤消它们,这个函数工作得很好。如果我在撤销后删除了recycleview中的第一个或最后一个项目,我会在那个位置看到一个空格,列表项目布局完全不可见,它只是白色的。然后,我在调用restore方法后添加了一个“recycleview.scrollToPosition ”:

    recycleAdapter.restoreItem(deletedItem, deletedIndex);
    recyclerView.scrollToPosition(deletedIndex);

在此更改之后,如果我从recycleview中删除第一个项目,而不是单击“撤消”,则先前删除的项目将正确还原,但如果我从“recycleview”中删除最后一个项目并单击“撤消”(undo),我仍然会看到一个空白(白色)项目。

你能帮我一下吗?可能是什么问题?如果你需要进一步的细节,我可以张贴更多的代码或告诉更多的应用程序。

编辑于2018年10月6日,我附加了RecyclerItemTouchHelper类,因为在我看来,这导致了问题:

public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
    private RecyclerItemTouchHelperListener listener;
    private Context mContext;

    public RecyclerItemTouchHelper(Context mContext, int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
        super(dragDirs, swipeDirs);
        this.listener = listener;
        this.mContext = mContext;
    }

    //This is not used
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        if (listener != null) {
            listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
        }
    }

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        View list_foreground = ((RecycleAdapter.mViewHolder)viewHolder).list_foreground;
        getDefaultUIUtil().clearView(list_foreground);
    }

    @Override
    public int convertToAbsoluteDirection(int flags, int layoutDirection) {
        return super.convertToAbsoluteDirection(flags, layoutDirection);
    }

    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (viewHolder != null) {
            View list_foreground = ((RecycleAdapter.mViewHolder)viewHolder).list_foreground;
            getDefaultUIUtil().onSelected(list_foreground);
        }
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

        float mdX = dX / 1;

        if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){

            Bitmap icon;
            Paint p = new Paint();

            Resources resources = mContext.getResources();

            View itemView = viewHolder.itemView;
            float height = (float) itemView.getBottom() - (float) itemView.getTop();
            float width = height / 3;

            if(dX > 0){ //Swipe right
                p.setColor(Color.parseColor("#D32F2F"));
                RectF background = new RectF((float) itemView.getLeft() , (float) itemView.getTop(), mdX, (float) itemView.getBottom());
                c.drawRect(background,p);
                icon = BitmapFactory.decodeResource(resources, R.drawable.ic_delete_white);
                RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
                c.drawBitmap(icon,null,icon_dest,p);
            } else { //Swipe left
                p.setColor(Color.parseColor("#388E3C"));
                RectF background = new RectF((float) itemView.getRight() + mdX, (float) itemView.getTop(), (float) itemView.getRight(), (float) itemView.getBottom());
                c.drawRect(background,p);
                icon = BitmapFactory.decodeResource(resources, R.drawable.ic_edit_white);
                RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
                c.drawBitmap(icon,null,icon_dest,p);
            }
        }
        super.onChildDraw(c, recyclerView, viewHolder, mdX, dY, actionState, isCurrentlyActive);
    }

    @Override
    public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        View list_foreground = ((RecycleAdapter.mViewHolder)viewHolder).list_foreground;
        getDefaultUIUtil().onDrawOver(c, recyclerView, list_foreground, dX, dY, actionState, isCurrentlyActive);
    }
}

下面是滑动的活动实现:

    @Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction, final int position) {
    //Swipe LEFT to DELETE
    if (direction == ItemTouchHelper.RIGHT) {
        Snackbar snackbar = Snackbar.make(rootLayout, "Phase " + (position + 1) + " is removed!", Snackbar.LENGTH_LONG);

        //Backup of removed item dor UNDO purpose
        final SequenceItem deletedItem = sequenceItemList.get(viewHolder.getAdapterPosition());
        final int deletedIndex = viewHolder.getAdapterPosition();

        //Remove the item from recyclerview
        recycleAdapter.removeItem(viewHolder.getAdapterPosition());

        snackbar.setAction(R.string.undo, new OnClickListener() {
            @Override
            public void onClick(View v) {
                //Restore deleted item
                recycleAdapter.restoreItem(deletedItem, deletedIndex);
                recyclerView.scrollToPosition(deletedIndex);

            }
        }).addCallback(new Snackbar.Callback() {
            @Override
            public void onDismissed(Snackbar snackbar, int dismissType) {
                super.onDismissed(snackbar, dismissType);

                if (dismissType != DISMISS_EVENT_ACTION) {
                    //Delete the item from the database
                    databaseHelper.removePhase(deletedItem);
                    Toast.makeText(getApplicationContext(), R.string.phase_successfully_deleted, Toast.LENGTH_LONG).show();
                }
            }
        });
        snackbar.setActionTextColor(getResources().getColor(R.color.warningColor));
        snackbar.show();
    }
    //Swipe RIGHT to EDIT
    else {
        Intent intent = new Intent(this, AddPhaseActivity.class);
        intent.putExtra("dbPosition", (long) viewHolder.itemView.getTag());
        intent.putExtra("rvPosition", position);
        recycleAdapter.notifyItemChanged(position);
        this.startActivity(intent);
    }
}

共有1个答案

白信鸿
2023-03-14

您的代码没问题。这种奇怪的性能的唯一可能的地方是下面的功能。

@Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { View list_foreground = ((RecycleAdapter.mViewHolder)viewHolder).list_foreground; getDefaultUIUtil().clearView(list_foreground); }

你清除了错误的视图。尝试清除项目的根视图,例如

@覆盖公共无效clearView(RecyclerView,RecyclerView.ViewHolderviewHolder){View itemView=((RecycleAdapter.mViewHolder)viewHolder). itemView; getDefaultUIUtil(). clearView(itemView);}

公共void更改为onchildraw(Canvas c、RecyclerView和RecyclerView、recycerView.ViewHolder和viewholders、float dX、float dY、int actionState、boolean isCurrentlyActive)方法。

View list_foreground=((recycledapter.mViewHolder)viewHolder)。列表_前景;getDefaultUIUtil()。onDraw(c,recyclerView,list_foreground,dX,dY,actionState,isCurrentlyActive)

而不是

super.onChildDraw(c, recyclerView, viewHolder, mdX, dY, actionState, isCurrentlyActive);

它会解决你的问题。

解释:

问题的根源在于onchildraw方法调用

super.onChildDraw(c, recyclerView, viewHolder, mdX, dY, actionState, isCurrentlyActive);

它在内部调用< code>onDraw(Canvas c,RecyclerView recyclerView,View view,float dX,float dY,int actionState,boolean isCurrentlyActive)函数,传递< code>viewHolder.itemView作为< code>view的参数,并实现对它的转换,如

< code > view . settranslationx(dX);view . settranslationy(dY);

但是清晰的视野就像

    @Override
    public void clearView(View view) {
        view.setTranslationX(0f);
        view.setTranslationY(0f);
    }

因此,在您的情况下,ChildDrawclearView上的功能适用于不同的视图。

 类似资料:
  • Revert 命令可以撤消之前做过的某个提交。 练习 1,先查看一下项目的提交历史: → git log --oneline fb11f83 让 README.md 标题的首字母大写 0fd9dac 让标题微笑 7086650 添加 .gitignore b5773ad 设置相关资源文档标题 23f3c2b 添加相关资源文档 a454700 设置说明文档的标题 39975b3 初始化 “添加 .

  • 问题内容: 我已经阅读了关于此的所有问题,但仍然没有找到答案。因此,请勿将其标记为重复项。 我正在将AngularFire与Angular 2和Typescript一起使用。我正在使用从端点提取24条最近记录的列表。这是我的代码: 如预期的那样,这将返回24个最新故事的列表,但是当我使用以下命令将它们呈现在页面上时: 它在顶部显示最旧的故事,在底部显示最新的故事。我了解为什么会这样,但我并不是说这

  • 我实现了一个可撤消的JTextField,问题是当我创建多个JTextField时,它只是撤消创建的最后一个实例。代码如下-要复制,请在第三个字段中输入一些文本,然后在第一个文本字段中输入一些代码并键入ctrl-z以撤消-它只从第三个文本字段中删除文本。有人能看到我做错了什么吗?

  • 问题内容: 假设我有以下两个变量: 我怎样才能获得的价值是价值?也就是说,如何展开unicode格式,但保留十六进制的值? 如果我这样做: 那是不对的… 救命! 问题答案: U + 0000和U + 00FF之间的代码点以ISO 8859-1或Latin 1编码映射到相同的字节值。

  • 在任何一个阶段,你都有可能想要撤消某些操作。 这里,我们将会学习几个撤消你所做修改的基本工具。 注意,有些撤消操作是不可逆的。 这是在使用 Git 的过程中,会因为操作失误而导致之前的工作丢失的少有的几个地方之一。 有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令尝试重新提交: $ git commit --amend 这个

  • 这就是我想要的: 如上图所示,我想在上画一条中心线,然后在滚动时获得中心项(以及向左或向右移动) 以下是我尝试画一个水平的: 有没有办法知道哪个项目移动到了回收视图的中心?如何将向左或向右滚动一个位置? 更新:我尝试使用滚动侦听器来获得中间位置,但它不能作为一个方面。 并得到结果: 我只想在蓝色上更改选中的项目(使文本变为白色)