为什么在clearView之后调用ItemTouchHelper.Callback的onChildDraw

时间:2016-01-05 10:17:08

标签: android

事情是,我想在物品在RecyclerView中拖动时对物品进行提升。

根据文档说的内容,我应该在ItemTouchHelper.Callback#onChildDraw中自定义拖动的视图行为,因为它说

  

如果您想自定义视图对用户互动的响应方式,这是一个覆盖的好地方。

然后我应该在ItemTouchHelper.Callback#clearView中清除我的自定义,因为它说

  

当用户与元素的交互结束并且它也完成了动画时,由ItemTouchHelper调用。

但问题是onChildDraw将始终在clearView之后再次调用。

因此,即使我清除clearView中的自定义行为,仍会在onChildDraw中重新调用。那么clearView的目的是什么?

这是我的代码:

class MyItemTouchCallback extends ItemTouchHelper.Callback {

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        return makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP | ItemTouchHelper.DOWN);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        mAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder,
                            float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        // Set elevation for dragged itemView
        ViewCompat.setElevation(viewHolder.itemView, getResources().getDimension(R.dimen.common_elevation));
    }

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        // Clear elevation for dragged itemView
        ViewCompat.setElevation(viewHolder.itemView, 0);
    }
}

2 个答案:

答案 0 :(得分:2)

当然我们可以通过一个技巧解决这个问题,这很容易理解。在清除拖动的itemView时,请记住使用布尔变量viewBeingCleared,然后我们可以决定是否在onChildDraw中调用自定义代码。

然而,这不是最好的解决方案。我们最好知道原因,然后我们知道,不是吗?

诀窍解决方案:

class MyItemTouchCallback extends ItemTouchHelper.Callback {

    boolean viewBeingCleared;

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        return makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP | ItemTouchHelper.DOWN);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        mAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder,
                            float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        if (viewBeingCleared) {
            viewBeingCleared = false;
        } else {
            ViewCompat.setElevation(viewHolder.itemView, getResources().getDimension(R.dimen.common_elevation));
        }
    }

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        ViewCompat.setElevation(viewHolder.itemView, 0);
        viewBeingCleared = true;
    }
}

答案 1 :(得分:0)

只需检查 if (isCurrentlyActive)