Android Nougat clipPath not working during animation

I created a circular clip path on my canvas, and I have a column of numbers that animates on the canvas, so I see numbers that come to life in the cropped section and animate. Here is the code for clipping:

mClipPath.addCircle((w / 2f), (h / 2f), radius, Path.Direction.CW); canvas.clipPath(mClipPath, Region.Op.INTERSECT); 

As you can see, 0 animation and 1 animation (numbers on the right). enter image description here

But in some cases, clipping does not happen properly during the animation (3 and 4 on the left).

enter image description here

This happens only in Nougat.

+5
source share
3 answers

I see the same problem. By scrolling through the RecyclerView containing the CircleCropDrawable below, I can see the pop-out flash between the cropped and uncropped ones depending on the scroll position.

However, through the trial version and the error, I saw that this only happened when Path crossed the edge of the possible. Reducing the radius by 1dp fixes the problem (less than 1dp does not work)

CircleCropDrawable.java

 package com.someone.android.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Path; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; import android.util.TypedValue; public class CircleCropDrawable extends Drawable { private final Context mContext; private final Drawable mDrawable; public CircleCropDrawable(Context context, Drawable drawable) { mContext = context; this.mDrawable = drawable; } @Override public void draw(@NonNull Canvas canvas) { final float width = getBounds().width(); final float height = getBounds().height(); final Path path = new Path(); // There seems to be a bug in N where the clip path doesn't work when animating // without a 1dp reduction in radius, the drawable unclips when scrolling in a RecyclerView float inset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, mContext.getResources().getDisplayMetrics()); path.addCircle(width / 2, height / 2, Math.min(width / 2, height / 2) - inset, Path.Direction.CW); canvas.clipPath(path); mDrawable.draw(canvas); } @Override protected void onBoundsChange(Rect bounds) { mDrawable.setBounds(bounds); } @Override public int getIntrinsicWidth() { return mDrawable.getIntrinsicWidth(); } @Override public int getIntrinsicHeight() { return mDrawable.getIntrinsicHeight(); } @Override public void setAlpha(int i) { mDrawable.setAlpha(i); } @Override public void setColorFilter(ColorFilter colorFilter) { mDrawable.setColorFilter(colorFilter); } @Override public int getOpacity() { return mDrawable.getOpacity(); } } 
+1
source

I registered a bug on Google and it looks like it was resolved. Here is the error link:

https://code.google.com/p/android/issues/detail?id=225016

+1
source

We fixed the problem by disabling hardware acceleration for this view, for example:

 myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
0
source

Source: https://habr.com/ru/post/1257550/


All Articles