Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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).

like image 384
dimsuz Avatar asked Mar 15 '15 13:03

dimsuz


2 Answers

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.)

like image 200
Lorne Laliberte Avatar answered Oct 24 '22 05:10

Lorne Laliberte


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 } 
like image 35
dimsuz Avatar answered Oct 24 '22 05:10

dimsuz