clearAnimation()解决setVisibility()无效问题

来源:互联网 发布:google translate软件 编辑:程序博客网 时间:2024/06/15 05:56

跟甜同学一起搞一个退场动画,第一次播放没问题,第二次播放就发现有个view会先闪出来一下,然后再执行从0到1的alpha动画。但是代码里明明已经用setVisibility(INVISIBLE)隐藏这个view了,为什么没有生效呢?Google了一下,有人说要调一下clearAnimation(),试了一下果然好了。。。

那么为什么加上这句就好了呢?得去看看framework的代码了,首先看一下View的clearAnimation():

    public void clearAnimation() {        if (mCurrentAnimation != null) {            mCurrentAnimation.detach();        }        mCurrentAnimation = null;        invalidateParentIfNeeded();    }
主要就是把mCurrentAnimation这个变量置空。这个变量是protected类型的,外面使用的话要通过getAnimation()这个接口:

    public Animation getAnimation() {        return mCurrentAnimation;    }
搜了一下发现ViewGroup的dispatchDraw()里用到了这个方法来判断是否要drawChild(),如果getAnimation()不为空,即使mViewFlags不是VISIBLE也要画:

    protected void dispatchDraw(Canvas canvas) {        ... ...        if ((flags & FLAG_USE_CHILD_DRAWING_ORDER) == 0) {            for (int i = 0; i < count; i++) {                final View child = children[i];                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {                    more |= drawChild(canvas, child, drawingTime);                }            }        } else {            for (int i = 0; i < count; i++) {                final View child = children[getChildDrawingOrder(count, i)];                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {                    more |= drawChild(canvas, child, drawingTime);                }            }        }        ... ...    }
OK,那么下面的问题就是,之前的动画已经结束了,为什么mCurrentAnimation没有被置空?在ViewGroup的finishAnimationView()方法里找到这一段:

void finishAnimatingView(final View view, Animation animation) {    ... ...        if (animation != null && !animation.getFillAfter()) {            view.clearAnimation();        }    ... ...}
也就是说,如果我们调用了setFillAfter(true),动画结束的时候就不会调用clearAnimation(),mCurrentAnimation就不会被置空了。在我们实现的动画里,确实调用了setFillAfter(true)。。。

总结:做动画时,如果调用了setFillAfter(true),动画结束后如果要设置该view的可见性,需要先调用一次clearAnimation()。

0 0
原创粉丝点击