android 动画导致 setVisibility和 removeView 失效(源码分析)原因分析

前段时间在项目中遇见偶现setVisibility(View.GONE)removeView(view)失效问题,通过各种追踪分析最后发现是由于 View 在执行动画过程中调用 setVisibilityremoveView 失效导致的。

在动画过程中setVisibility(View.GONE) 失效原因分析

ViewGroup 中的 dispatchDraw 函数中有以下代码:

image.png

通过以上代码可知当 View 存在执行的动画时则忽略了 View.GONE 属性会继续绘制出现。
解决方案是:
在执行动画的 View调用 setVisibility前先调用 clearAnimation
在动画执行完后也调用clearAnimation,防止出现 setVisibility 失效问题出现。

在动画过程中removeView(View view) 失效原因分析

源码分析:

    public void removeView(View view) {
        if (removeViewInternal(view)) {
            requestLayout();
            invalidate(true);
        }
    }

removeView中调用removeViewInternal(view)再走到removeViewInternal(int index, View view),其里面的代码比较多不全部贴出,里面关键代码

image.png

红框中显示如果当前 view 存在动画则会走到addDisappearingView函数,其代码

/**
     * Add a view which is removed from mChildren but still needs animation
     *
     * @param v View to add
     */
    private void addDisappearingView(View v) {
        ArrayList<View> disappearingChildren = mDisappearingChildren;

        if (disappearingChildren == null) {
            disappearingChildren = mDisappearingChildren = new ArrayList<View>();
        }

        disappearingChildren.add(v);
    }

通过注释和代码知道是把当前的 view 放到mDisappearingChildren列表中,这个列表里面存放的是存在动画的待移出的 view
ViewGroup 中的 dispatchDraw(Canvas canvas)函数中发现用到了 mDisappearingChildren这个列表

image.png

通过注释和代码显示这些待消失的view会继续被绘制
总结分析:执行动画过程中的 view 如果 被 remove 掉还是会被绘制,只是系统为了保证动画的完整性
解决方案:在remove掉存在动画的 view 之前先 clearAnimation

个人思考:

android系统为了保证 View动画的完整性,在 View 执行动画过程中不会把 View GONEremove 掉。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。