📜 ⬆️ ⬇️

Reveal for everyone!



Hello, Habrovchane !
I'll tell you how I implemented Circual Reveal animation from Lollipop, lowering the threshold to Gingerbread.

In Lollipop, native HardwareCanvas, RenderNodeAnimator classes appeared for smoother animation and rendering, and Ripple and Reveal animation is built on it. Now many elements are drawn and animated at the level of iron.
')


Native animation



public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) { return new RevealAnimator(view, centerX, centerY, startRadius, endRadius); } 


As described in the documentation, RevealAnimator is an animated circle trim. It, in turn, is derived from RenderNodeAnimator and calls the native method.

  private static native long nCreateRevealAnimator( int x, int y, float startRadius, float endRadius); 


There is already trimming the circle, through:

 RevealAnimator::RevealAnimator(int centerX, int centerY, float startValue, float finalValue) : BaseRenderNodeAnimator(finalValue) , mCenterX(centerX) , mCenterY(centerY) { setStartValue(startValue); } float RevealAnimator::getValue(RenderNode* target) const { return target->properties().getRevealClip().getRadius(); } //     void RevealAnimator::setValue(RenderNode* target, float value) { target->animatorProperties().mutableRevealClip().set(true, mCenterX, mCenterY, value); } 


Decision



My solution is relatively simple: I created my own custom Layouts (Frame | Linear, original, almost untouched), changing only the method where children are drawn

 @Override protected boolean drawChild(@NonNull Canvas canvas, @NonNull View child, long drawingTime) { if(!mClipOutlines && child != mTarget) return super.drawChild(canvas, child, drawingTime); final int state = canvas.save(); mRevealPath.reset(); mRevealPath.addCircle(mCenterX, mCenterY, mRadius, Path.Direction.CW); canvas.clipPath(mRevealPath); boolean isInvalidated = super.drawChild(canvas, child, drawingTime); canvas.restoreToCount(state); return isInvalidated; } 


I just ask the canvas to trim a certain area during the animation. The animation is implemented through ObjectAnimator (thanks to Jake Wharton, nineoldsandroid).



The article turned out a bit crumpled, if you have any questions, write in the comments, I will add the article :)

Thanks for attention!
Github

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


All Articles