みんなに見せて!



こんにちは、 ハブロフスク市民
LollipopからCircual Revealアニメーションを実装し、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); } 


解決策



私の解決策は比較的単純です:独自のカスタムレイアウト(フレーム|線形、元の、ほとんど手を加えない)を作成し、子が描画されるメソッドのみを変更します

 @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; } 


アニメーション中にキャンバスに特定の領域を切り抜くだけです。 アニメーションはObjectAnimatorを介して実装されます(Jake Wharton、nineoldsandroidに感謝)。



記事が少しくしゃくしゃになっていることがわかりました。質問がある場合は、コメントを書いてください。記事を補足します:)

ご清聴ありがとうございました!
Github

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


All Articles