美文网首页
android 动画导致 setVisibility和 remo

android 动画导致 setVisibility和 remo

作者: 十七17 | 来源:发表于2019-11-28 11:34 被阅读0次

    前段时间在项目中遇见偶现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 掉。

    相关文章

      网友评论

          本文标题:android 动画导致 setVisibility和 remo

          本文链接:https://www.haomeiwen.com/subject/rfemwctx.html