animateLayoutChanges与嵌套布局不兼容?

Che*_*hen 42 android android-animation android-layout

我有一个嵌套的布局,如下所示:

 <LinearLayout>     <!----Parent layout--->
    <LinearLayout>    <!-----child 1--->
       ...
    </LinearLayout>   <!----child 1 ended--->
    <LinearLayout>    <!-----child 2--->
       ...
    </LinearLayout>   <!----child 2 ended--->
 </LinearLayout>    <!----Parent endded--->
Run Code Online (Sandbox Code Playgroud)

我现在遇到的问题是,由于我的所有数据项都在子项1或子项2中Linearlayout,如果我添加或删除项目,子行为布局将使用animateLayoutChanges的效果进行动画处理,但父布局不会执行任何动画.(我已android:animateLayoutChanges设置true为所有线性布局).特别是当我删除子1中的项目时,动画效果变得怪异(基本上,当孩子1仍然在做动画时,孩子2会跳起来).

有谁知道如何解决这个问题?

谢谢

UPDATE

在我发布这个问题后不久,我在LayoutTransition API的android开发者网站上发现了这个问题.

由于各种布局级别的相互关系,在嵌套视图层次结构的多个级别使用LayoutTransition可能不起作用.

那么有没有人有任何关于这个问题的建议呢?

Tim*_*dén 82

animateLayoutChanges属性使用LayoutTransitions,它可以为布局的子项设置动画,从Android 4.0开始,布局层次结构中的祖先一直到树的顶部.在Honeycomb中,只有布局的孩子才会被动画化.有关详细信息,请参阅此Android开发者博客帖子.

不幸的是,似乎目前还没有一种简单的方法可以让布局的兄弟对它做出反应LayoutTransitions.您可以尝试使用a TransitionListener在更改布局边界时收到通知,并使用Animators相应地移动兄弟视图.请参阅此帖子中的 Chet Haase的第二个答案.

编辑 -原来有一种方式.在Android 4.1+(API级别16+)中,您可以使用布局转换类型CHANGING,默认情况下禁用该类型.要在代码中启用它:

ViewGroup layout = (ViewGroup) findViewById(R.id.yourLayout);
LayoutTransition layoutTransition = layout.getLayoutTransition();
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
Run Code Online (Sandbox Code Playgroud)

因此,在您的示例中,要将子2布局设置为动画,您需要为其启用CHANGING布局转换.然后,当其父级的边界发生变化时,将应用转换.

有关详细信息,请参阅此DevBytes视频.

  • layoutTransition.enableTransitionType(LayoutTransition.CHANGING); 确实适用于嵌套布局,只需将其添加到父布局即可.然而,消失的视图将不同步,您将看到当您离开视图时,父布局将在孩子之前完成.要解决此问题,您还需要修改子布局转换并设置layoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING,0); 通过这样做出现并消失将与父母和孩子同步. (28认同)
  • @chronogenre setStartDelay确实在两个转换之间同步,但消失的视图正在淡化其旁边的移动子.淡出完成后有没有办法启动CHANGING运动? (3认同)

Sam*_*hen 27

好的,消化完第一个答案后,我在这里简单说一下,对于那些android:animateLayoutChanges="true"NESTED布局中使用时没有得到正确动画结果的人:

  1. 请确保您添加android:animateLayoutChanges="true"将待调整 ViewGroupLinearLayout/ RelativeLayout/ FrameLayout/ CoordinatorLayout)。

  2. 使用setVisibility()来控制你的知名度目标 View

  3. 从这里仔细听,添加android:animateLayoutChanges="true" ViewGroup你的意志来调整大小 ViewGroup,此 ViewGroup必须是谁包装的所有位置变化的一个View受动画。

  4. Activity之前添加以下代码setVisibility(),这里rootLinearLayoutViewGroup我上面提到的外部:

     LayoutTransition layoutTransition = rootLinearLayout.getLayoutTransition();
     layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
    
    Run Code Online (Sandbox Code Playgroud)

前:

在此处输入图片说明

后:

在此处输入图片说明


提醒:如果你错过了第三步,你会得到空指针异常。

祝你好运!

  • 感谢您添加 GIF 的努力。多谢。+1 (5认同)

小智 6

我们已经将android:animateLayoutChanges属性添加到LinearLayout中,但是更改并未触发动画。要解决此问题,请使用以下代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
((ViewGroup) findViewById(R.id.llRoot)).getLayoutTransition()
      .enableTransitionType(LayoutTransition.CHANGING);
}
Run Code Online (Sandbox Code Playgroud)

更多细节


Mic*_*ael 6

作为 Kotlin 扩展

fun ViewGroup.forceLayoutChanges() {
    layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
}
Run Code Online (Sandbox Code Playgroud)

用法

someContainer.forceLayoutChanges()
Run Code Online (Sandbox Code Playgroud)

笔记:

根据我的经验,当容器是深层嵌套布局时会发生这种情况。由于某种原因android:animateLayoutChanges="true",它不起作用,但使用此功能将迫使它工作。