View的Detach状态对动画的影响
起因是在用外部是ViewPager2
实现的banner控件时,每个View
有浮动的动画成果,在滑动切换后,动画隐没。咱们都晓得ViewPager2
的外部是用RecyclerView
来实现的,而RecyclerView
复用和回收View
时会将View
增加和移除,第一想法是Detach
对动画有影响,在试验过这个想法,开始剖析
切入点
startAnimation
、dispatchDetachedFromWindow
源码剖析
startAnimation
public void startAnimation(Animation animation) { animation.setStartTime(Animation.START_ON_FIRST_FRAME); setAnimation(animation); invalidateParentCaches(); invalidate(true);}public void setAnimation(Animation animation) { mCurrentAnimation = animation; ...}
能够看到只是简略给mCurrentAnimation
进行了赋值,其余都是动画相干的设置,而后执行了invalidate
,那么动画是怎么被执行的呢?猜想onDraw
里必定有猫腻,咱们再看看另一个切入点
dispatchDetachedFromWindow
void dispatchDetachedFromWindow() { ... onDetachedFromWindowInternal(); ... if (listeners != null && listeners.size() > 0) { ... // 分发给内部回调 for (OnAttachStateChangeListener listener : listeners) { listener.onViewDetachedFromWindow(this); } } ... mAttachInfo = null; if (mOverlay != null) { // 分发给Overlay mOverlay.getOverlayView().dispatchDetachedFromWindow(); } notifyEnterOrExitForAutoFillIfNeeded(false);}protected void onDetachedFromWindowInternal() { ... mCurrentAnimation = null; ...}
只是简略的将mCurrentAnimation
置为null
,onDraw
的嫌疑更大了,咱们追踪mCurrentAnimation
的usage
,发现在boolean draw(Canvas canvas, ViewGroup parent, long drawingTime)
中有应用,那也根本确定了咱们的猜想
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { ... final Animation a = getAnimation(); if (a != null) { more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired); ... } else { ... } return more;}private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime, Animation a, boolean scalingRequired) { ... if (!initialized) { ... onAnimationStart(); } ... return more;}
看到onAnimationStart
咱们就能够确定了,动画的确是通过onDraw
来执行的,detached
后,获取不到动画,也就进行了。但具体动画是怎么执行的不在探讨范畴内。