View的Detach状态对动画的影响

起因是在用外部是ViewPager2实现的banner控件时,每个View有浮动的动画成果,在滑动切换后,动画隐没。咱们都晓得ViewPager2的外部是用RecyclerView来实现的,而RecyclerView复用和回收View时会将View增加和移除,第一想法是Detach对动画有影响,在试验过这个想法,开始剖析

切入点

startAnimationdispatchDetachedFromWindow

源码剖析

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置为nullonDraw的嫌疑更大了,咱们追踪mCurrentAnimationusage,发现在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后,获取不到动画,也就进行了。但具体动画是怎么执行的不在探讨范畴内。