Android 为什么选择ItemTouchHelper.Callback';s onchildraw将在clearView之后调用

Android 为什么选择ItemTouchHelper.Callback';s onchildraw将在clearView之后调用,android,Android,问题是,我想在项目被拖入RecyclerView时对其执行提升 根据文档所述,我应该在中自定义拖动视图的行为,因为 如果您想自定义视图对用户交互的响应方式,那么这是一个覆盖的好地方 然后我应该清除中的自定义项,因为它显示 当用户与元素的交互结束并完成其动画时,ItemTouchHelper将调用该函数 但问题是onchildraw总是在clearView之后被再次调用 因此,即使我清除了clearView中的定制行为,它仍将在onchildraw中重新调用。那么clearView的目的是什么 这

问题是,我想在项目被拖入RecyclerView时对其执行提升

根据文档所述,我应该在中自定义拖动视图的行为,因为

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

然后我应该清除中的自定义项,因为它显示

当用户与元素的交互结束并完成其动画时,ItemTouchHelper将调用该函数

但问题是
onchildraw
总是在
clearView
之后被再次调用

因此,即使我清除了
clearView
中的定制行为,它仍将在
onchildraw
中重新调用。那么
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);
    }
}

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

然而,这并不是最好的解决方案。我们最好知道为什么,然后我们就会知道怎么做,不是吗

技巧解决方案:

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

松开手指时,
isCurrentlyActive
值变为false。仍将调用
onchildraw()
,但不再需要设置高程。另外,不要每次都在
onchildraw()
中加载维度资源-在构造函数中加载一次并保存到字段。