乐趣区

关于android:View的Detach状态对动画的影响

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后,获取不到动画,也就进行了。但具体动画是怎么执行的不在探讨范畴内。

退出移动版