如何在项目动画期间禁用 RecyclerView 项目装饰绘图

How to disable RecyclerView item decoration drawing for the duration of item animations

我有一些基本的物品装饰,用 ItemDecoration.onDrawOver 方法画了一些东西。

这个 RecyclerView 也设置了 DefaultItemAnimator。 动画正在运行,一切都很好。除了一件事。

当所有现有项目与此适配器中的新项目集交换时,装饰将在动画 运行 时显示。

我需要一种隐藏它们的方法。 当动画结束时,它们需要显示,但当它是 运行 时,它们必须隐藏。

我尝试了以下方法:

public void onDrawOver(..., RecyclerView.State state) {
    if(state.willRunPredictiveAnimations() || state.willRunSimpleAnimations()) {
        return;
    }
    // else do drawing stuff here
}

但这没有帮助。装饰仅在动画的短时间内被移除,但随后在仍然 运行.

时再次出现

设置还包括一个 RecyclerView.Adapter ,其中 hasStableIds() (以防万一)。

自己找到答案:

要在项目动画期间隐藏项目装饰,可以简单地使用此检查 onDraw/onDrawOver:

public void onDrawOver(..., RecyclerView parent, ...) {
    if(parent.getItemAnimator() != null && parent.getItemAnimator().isRunning()) {
        return;
    }
    // else do drawing stuff here
}

这可能在某种程度上取决于您使用的动画类型,但至少对于 DefaultItemAnimator 您需要考虑在动画期间完成的 X/Y 转换。您可以使用 child.getTranslationX()child.getTranslationY().

获取这些值

例如,对于onDraw/onDrawOver的垂直情况:

private void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();
    final int childCount = parent.getChildCount();
    final int dividerHeight = mDivider.getIntrinsicHeight();

    for (int i = 1; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
        final int ty = (int)(child.getTranslationY() + 0.5f);
        final int top = child.getTop() - params.topMargin + ty;
        final int bottom = top + dividerHeight;
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

(如果您需要支持 < API 11,您可能更愿意使用 ViewCompat.getTranslationY(child)。)

注意:对于其他类型的动画,可能需要进行额外的调整。 (例如,可能还需要考虑水平平移。)

您可以尝试检查子 alpha(仅针对案例默认动画)。如果 alpha 0 则什么都不做