删除子视图时,不会运行LayoutTransition.DISAPPEARING动画

时间:2015-10-07 15:47:04

标签: android android-animation

我有一个FrameLayout容器,我试图对其进行动画处理。我在视图上调用了container.setLayoutTransition(layoutTransition),但是当我稍后调用container.removeView(v)时,DISAPPEARING动画未被执行,视图就会被立即删除。

这是我的过渡代码:

LayoutTransition layoutTransition = new LayoutTransition();
layoutTransition.setAnimator(LayoutTransition.APPEARING,
    ObjectAnimator.ofFloat(null, View.TRANSLATION_Y, toolHeight, 0f));
layoutTransition.setStartDelay(LayoutTransition.APPEARING, 0);
layoutTransition.setDuration(LayoutTransition.APPEARING, 1000);
layoutTransition.setAnimator(LayoutTransition.DISAPPEARING,
    ObjectAnimator.ofFloat(null, View.TRANSLATION_Y, 0f, toolHeight));
layoutTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
layoutTransition.setDuration(LayoutTransition.DISAPPEARING, 1000);
container.setLayoutTransition(layoutTransition);

交换视图我这样做:

if (container.getChildCount() > 0) {
  for (int i = container.getChildCount() - 1; i >= 0; i--) {
    container.removeViewAt(i);
  }
}
container.addView(newView);

我放慢了动画速度以确认情况,我可以清楚地看到APPEARING转换已正确执行,但DISAPPEARING转换不是,视图只是立即删除。

我发现,如果我从LayoutTransition.removeChild()方法移除视图,它会起作用,但这会增加相当复杂的效果,而这似乎并不是必需的。这就是:

if (container.getChildCount() > 0) {
  final View v = container.getChildAt(0);
  container.getLayoutTransition().removeChild(container, v);
  container.getLayoutTransition().addTransitionListener(new LayoutTransition.TransitionListener() {
    @Override
    public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
    }

    @Override
    public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
      transition.removeTransitionListener(this);
      if (transitionType == LayoutTransition.DISAPPEARING) {
        container.removeView(view);
      }
    }
  }
}
container.addView(newView);

认为这很糟糕?这只是一次删除一个视图,如果容器中有多个视图,那么我必须添加一个转换监听器来计算执行时知道何时删除它自己,&#&# 39;一团糟。

删除本身很有意思,因为如果我只是将转换监听器放在LayoutTransition上并且它不会自行删除,那么消失的转换不会再次运行。

显然,我遗漏了与执行删除转换有关的事情。任何帮助将不胜感激。

修改

有人向我指出,添加观看会取消DISAPPEARING转换:

public class ViewGroup {
  private void addViewInner(...) {
    if (mTransition != null) {
      // Don't prevent other add transitions from completing, but cancel remove
      // transitions to let them complete the process before we add to the container
      mTransition.cancel(LayoutTransition.DISAPPEARING);
    }
  }
}

这对我来说并没有多大意义。想知道这里的推理是什么。

1 个答案:

答案 0 :(得分:4)

正如您已经注意到的那样,padding-bottom并不像某些较新的API那样对动画类型进行真正的排序。它旨在一次处理单个项目更改。最干净的代码来自于自己对延迟进行排序,而不是链接监听器调用:

LayoutTransition

对于类似这样的事情,您可能会从Scenes获得更好的编排,但那就是API 19 +