在这里记录下编程开发的各种小技巧,帮助他人,成长自己。

  • View 的 detach 和 attach 可能会因为 Animation 而变得混乱,不经意间就造成 View 假死,例如:

    mView.startAnimation(disappearAnimation);
    ViewGroup parent = (ViewGroup) mView.getParent();
    parent.removeView(mView); // 移除 view 时伴随动画
    //...
    parent.addView(mView); // 动画未结束时又将 view 加回来
    mView.startAnimation(appearAnimation);

    现象:​mView 无法接收事件,使用 uiautomatorviewer 时也无法查看其信息

    原因:当 mView.getAnimation() != null ​时,parent.removeView() 并不会detach 掉 mView,而是暂时将 mView 放入的成员变量 mDisappearingChildren 中,在 parent.dispatchDraw() 中当 mView.getAnimation() != null 且 动画已经结束时,才执行 mView 的 detach逻辑。但是当动画中途执行 mView.StartAnimation(newAnimation) 时, parent.dispatchDraw() 中 mView.getAnimation() 所获取的对象已经变了,那么 detach 的时机也就变了。

    上述代码的执行顺序大致为:mView.startAnimation(disappearAnimation) -> parent.removeView -> mDisappearingChildren.add(mView) -> parent.addView -> mView.attach -> mView.startAnimation(appearAnimation) -> appearAnimation.end -> mDisappearingChildren.remove(mView) & mView.detach。最终 mView 处于 detach 状态,故而 View 会假死。

    现实场景:​当 fragment A 切换到 fragment B 时,如果转场动画还没结束时就快速按返回键使 fragment B pop 掉,最终会造成页面假死在 fragment A 上。QMUI 上就遇到这个问题,具体解决措施也可参考参考

      Android