我在滑动时有一个移除,它通过ItemTouchHelper实现了绘制背景(非常类似于Inbox应用程序)-通过覆盖onChilDraw方法并在提供的 Canvas 上绘制矩形:

    ItemTouchHelper mIth = new ItemTouchHelper(
        new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {

            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                remove(viewHolder.getAdapterPosition());
            }

            public boolean onMove(RecyclerView recyclerview, RecyclerView.ViewHolder v, RecyclerView.ViewHolder target) {
                return false;
            }

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

                View itemView = viewHolder.itemView;

                Drawable d = ContextCompat.getDrawable(context, R.drawable.bg_swipe_item_right);
                d.setBounds(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
                d.draw(c);

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

上面调用的remove方法在适配器中:
    public void remove(int position) {
       items.remove(position);
       notifyItemRemoved(position);
    }

背景画得很好,但是当调用notifyItemRemoved(根据Debugger先生)时,RecyclerView首先删除我的绿色背景,然后将两个相邻的项目推在一起。



我希望它在执行操作时将背景保持在那里(就像Inbox应用一样)。有什么办法吗?

最佳答案

我遇到了同样的问题,我不想引入一个新的lib来修复它。 RecyclerView不会删除您的漂亮绿色背景,它只是在重绘自身,而ItemTouchHelper不会再绘制。实际上,它在绘制,但是dX为0,并且是从itemView.getLeft()(为0)到dX(为0)绘制的,因此您什么也看不到。它消耗太多,但我稍后会再讨论。

无论如何,当行设置动画时回到背景:我无法在ItemTouchHelperonChildDraw中做到这一点。最后,我必须添加另一个项目装饰器来执行此操作。它遵循以下原则:

public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (parent.getItemAnimator().isRunning()) {
        // find first child with translationY > 0
        // draw from it's top to translationY whatever you want

        int top = 0;
        int bottom = 0;

        int childCount = parent.getLayoutManager().getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getLayoutManager().getChildAt(i);
            if (child.getTranslationY() != 0) {
                top = child.getTop();
                bottom = top + (int) child.getTranslationY();
                break;
            }
        }

        // draw whatever you want

        super.onDraw(c, parent, state);
    }
}

此代码仅考虑动画的行,但您也应该考虑行下降的情况。如果您滑动删除最后一行,则会发生这种情况,上面的行将向下动画到该空间。

当我说您的ItemTouchHelper绘制的内容太多时,我的意思是:好像ItemTouchHelper保留了已删除行的ViewHolder,以备需要恢复时使用。除了刷VH之外,它还为这些VH调用onChildDraw。不确定这种行为对内存管理的影响,但是我需要在onChildDraw的开头进行一次额外的检查,以避免绘制“扇形”行。
if (viewHolder.getAdapterPosition() == -1) {
    return;
}

在您的情况下,它是从左= 0到右= 0绘制的,因此您看不到任何东西,但是开销很大。如果您开始看到以前刷掉的行绘制了它们的背景,那就是原因。

编辑:我已经去了这个,见这个blog post和这个github repo

关于android - RecyclerView ItemTouchHelper滑动删除动画,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31418905/

10-13 01:12