みんなに見せて!





こんにちは、 ハブロフスク市民

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



All Articles