
Здравствуйте, Хабровчане !
Я расскажу как я реализовал Circual Reveal анимацию из Lollipop, опустив порог до Gingerbread.
В Lollipop появились нативные классы HardwareCanvas, RenderNodeAnimator для более плавной анимации и отрисовки, на нем построена Ripple и Reveal анимация. Теперь многие элементы рисуются и анимируются на уровне железа.
Родная анимация
public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) { return new RevealAnimator(view, centerX, centerY, startRadius, endRadius); }
Как описанно в документации, RevealAnimator — это анимированная обрезка круга. Он в свою очередь произошел от RenderNodeAnimator и вызывает нативный метод.
private static native long nCreateRevealAnimator( int x, int y, float startRadius, float endRadius);
Там уже и идет обрезка круга, через:
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); }
Решение
Мое решение относительно простое: я создал свои кастомные Layout'ы (Frame | Linear, оригинальные, почти нетронутые), изменив всего лишь метод, где рисуются дети
@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; }
Я лишь прошу canvas обрезать определненную область во время анимации. Анимация реализуется через ObjectAnimator (thanks to Jake Wharton, nineoldsandroid).
Статья получилась немного скомканной, если есть вопросы пишите в комментарии, дополню статью :)
Спасибо за внимание!
Github
