こんにちは、 ハブロフスク市民 !
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