如何指定TransitionManager.beginDelayedTransition仅影响直接子视图

问题描述 投票:1回答:2

我正在尝试将ConstraintLayout与使用动画上下滑动的视图结合使用。这些视图是垂直组织的,顶部是RecyclerView,下面是两个其他视图:

<constraint layout container>
    [                    ]
    [    recycler view   ] 
    [                    ]
    [48dp height 1st view]
    [48dp height 2nd view]
</constraint layout container>

动画非常简单:点击按钮时,第一个视图从容器底部移动到上面可以看到的位置,再次点击时,它向下移动并在第二个视图上保持重叠。当发生这种情况时,顶部的RecyclerView会改变高度,因为它被约束到第一个视图,否则会留下一个空的空间。

到目前为止这么好并且动画运行良好,但是当用户点击按钮太快时出现问题,导致以下错误:

    java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

在调查发生了什么之后,我发现这个问题是我用来制作变化动画的TransitionManager的结果。我发现有趣的是,当按下按钮以向上移动第一个视图(或向下,只是想象相反的步骤)时,管理器正在执行以下操作:

  • 淡出RecyclerView的第一个/最后一个视图(取决于你是否有一个反向布局或从结束启用的堆栈)
  • RecyclerView删除该视图
  • 减少RecyclerView的高度
  • 向上移动第一个视图

即使我在所有的地方指定我可以想象RecyclerView不应该动画项目更改,TransitionManager覆盖它,这意味着有一个窗口,当即将从RecyclerView删除相同的视图可以再次添加到同一个父级,该窗口是管理员淡出视图的时间。

由于淡入淡出动画并不那么快,用户可以在此期间轻松点击按钮两次,导致管理员重新添加已经在RecyclerView中的淡入淡出视图,从而在抛出上述错误时使应用程序崩溃。

因为这是RecyclerView内部引起的一个问题,所以我内心没有任何动画就完全没问题,因此我想知道如何在TransitionManager.beginDelayedTransition中指定只为ConstraintLayout的直接子视图制作动画,这样它就会没有动画RecyclerView内的视图。

相关文档对此没有任何启发,所以我在这里提出这个问题;如何限制转换为直接子视图?

如果它可能有用,我在这里包括过渡管理器的片段

    final ConstraintSet constraintSet;
    final ConstraintLayout constraintLayout;

    constraintSet = new ConstraintSet();
    constraintLayout = (ConstraintLayout) viewParent;

    TransitionManager.beginDelayedTransition(constraintLayout);

    constraintSet.clone(constraintLayout);
    constraintSet.connect(startId, startSide, endId, endSide, margin);
    constraintSet.applyTo(constraintLayout);
android android-recyclerview android-transitions
2个回答
4
投票

pskink在评论中发布了答案,但在两次要求他发布作为我接受的答案并且从未这样做之后,我会发布它并将其标记为已回答。

TransitionManager有一个方法excludeChildren,完美的工作,我正在寻找。您可以按类类型,特定视图的子项等使用。

编辑:添加请求的示例

    AutoTransition autoTransition = new AutoTransition();
    autoTransition.excludeChildren(R.id.recyclerView, true);
    TransitionManager.beginDelayedTransition(constraintLayout, autoTransition);

使用constraintLayout作为目标视图的父级,R.id.recyclerView是我不想要动画的父级的子视图,在这个具体示例中是。您还可以排除特定类的所有子项(例如EditText),依此类推。


1
投票

我这样修理它:

TransitionManager.beginDelayedTransition(
                        constraintLayout,
                        TransitionSet().apply {
                            ordering = TransitionSet.ORDERING_SEQUENTIAL
                            addTransition(ChangeBounds())
                            addTransition(Fade(Fade.IN))
                        }
                    )

它几乎与AutoTransition中的代码相同,如果我们不通过自定义转换,它是默认代码,但我删除了似乎是崩溃原因的addTransition(Fade(Fade.OUT))。至少对我而言,动画看起来与原作非常相似。

© www.soinside.com 2019 - 2024. All rights reserved.