animateLayoutChanges与嵌套布局不兼容?

时间:2013-11-20 18:23:09

标签: android android-layout android-animation

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

 <LinearLayout>     <!----Parent layout--->
    <LinearLayout>    <!-----child 1--->
       ...
    </LinearLayout>   <!----child 1 ended--->
    <LinearLayout>    <!-----child 2--->
       ...
    </LinearLayout>   <!----child 2 ended--->
 </LinearLayout>    <!----Parent endded--->

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

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

谢谢

更新

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

  

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

那么有没有人围绕这个问题提出建议呢?

5 个答案:

答案 0 :(得分:76)

animateLayoutChanges属性使用LayoutTransitions,它可以为布局的子项设置动画,并且从Android 4.0开始,布局层次结构中的祖先一直到树的顶部。在Honeycomb中,只有布局的孩子才会被动画化。有关详细信息,请参阅this Android Developers Blog post

不幸的是,似乎目前没有简单的方法让布局的兄弟对其LayoutTransitions作出反应。您可以尝试使用TransitionListener在更改布局边界时收到通知,并使用Animators相应地移动兄弟视图。请参阅this Google+ post中的Chet Haase的第二个答案。

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

ViewGroup layout = (ViewGroup) findViewById(R.id.yourLayout);
LayoutTransition layoutTransition = layout.getLayoutTransition();
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);

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

有关详细信息,请参阅this DevBytes video

答案 1 :(得分:17)

好吧,在总结了第一个答案之后,对于那些在 NESTED 布局中使用android:animateLayoutChanges="true"时无法获得正确动画效果的人,在这里我将其简化:

  1. 确保将android:animateLayoutChanges="true"添加到将要调整大小的 ViewGroupLinearLayout / RelativeLayout / {{1 }} / FrameLayout

  2. 使用CoordinatorLayout来控制目标 setVisibility()的可见性。

  3. 从这里仔细听,View添加到您的将要调整大小的外部 android:animateLayoutChanges="true"中, / strong> ViewGroup,此外部 ViewGroup必须是包裹受动画影响的所有位置变化ViewGroup的人。

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

    ViewGroup

之前:

enter image description here

之后:

enter image description here


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

祝你好运!

答案 2 :(得分:5)

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

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

More details

答案 3 :(得分:2)

作为Kotlin扩展程序

Container(
   height: 140,
   alignment: Alignment.topRight,
   child: Icon(Icons.edit),
),

用法

fun ViewGroup.forceLayoutChanges() {
    layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
}

注意:

以我的经验,这是在容器为深层嵌套布局时发生的。由于某些原因,someContainer.forceLayoutChanges() 无效,但是使用此功能将强制其工作。

答案 4 :(得分:1)

似乎父母的延迟转换也适用于动画。至少对我来说,以下代码给出了适当的展开/折叠动画。

expandTrigger.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        TransitionManager.beginDelayedTransition(parentLayout);
        expanded = !expanded;

        child1.setVisibility(expanded ? View.VISIBLE : View.GONE);
    }
});

对于深度嵌套的布局,您有时可能需要在调用TransitionManager的层次结构中使用更高的父级。