How to disable RecyclerView item decoration drawin

2020-02-24 13:24发布

问题:

I have some basic item decoration which draws some stuff in ItemDecoration.onDrawOver method.

This RecyclerView also has DefaultItemAnimator set on it. Animations are working, all is great. Except one thing.

When all existing items are swapped with a new item set in this adapter, the decorations are being shown while animation is running.

I need a way to hide them. When animation finishes, they need to be shown, but while it is running, they must be hidden.

I tried the following:

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

but this isn't helping. Decoration is only removed for the short period of animation, but then appears again while it is still running.

Also setup includes a RecyclerView.Adapter which hasStableIds() (in case that bit matters).

回答1:

It may depend somewhat on the type of animation you're using, but at least for DefaultItemAnimator you need to account for the X/Y translation being done during the animation. You can get these values with child.getTranslationX() and child.getTranslationY().

For example, for the vertical case of 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);
    }
}

(You may prefer to use ViewCompat.getTranslationY(child) if you need to support < API 11.)

Note: for other types of animations, additional adjustments may need to be made. (For example, horizontal translation might also need to be accounted for.)



回答2:

Found an answer myself:

To hide item decorations during an item animation one can simply use this check in onDraw/onDrawOver:

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


回答3:

You can try to check child alpha (only for case default animation). If alpha 0 then do nothing