前段时间在项目中遇见偶现setVisibility(View.GONE)
和 removeView(view)
失效问题,通过各种追踪分析最后发现是由于 View
在执行动画过程中调用 setVisibility
或 removeView
失效导致的。
在动画过程中setVisibility(View.GONE)
失效原因分析
在 ViewGroup
中的 dispatchDraw
函数中有以下代码:
通过以上代码可知当 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)
,其里面的代码比较多不全部贴出,里面关键代码
红框中显示如果当前 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
这个列表
通过注释和代码显示这些待消失的view
会继续被绘制
总结分析:执行动画过程中的 view
如果 被 remove
掉还是会被绘制,只是系统为了保证动画的完整性
解决方案:在remove
掉存在动画的 view
之前先 clearAnimation
个人思考:
android系统为了保证 View
动画的完整性,在 View
执行动画过程中不会把 View
GONE
或 remove
掉。