美文网首页
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