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

How to specify TransitionManager.beginDelayedTransition to affect only direct child views

我正在尝试将 ConstraintLayout 与随动画上下滑动的视图结合使用。 这些视图是垂直组织的,顶部有一个 RecyclerView,下面堆叠了另外两个视图:

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

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

到目前为止一切顺利,动画运行良好,但是当用户点击按钮太快时会出现问题,导致以下错误:

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

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

尽管我在所有我能想到的地方都指定了 RecyclerView 不应该为项目更改设置动画,但 TransitionManager 覆盖了它,这意味着 window 当即将从 RecyclerView 中删除的相同视图可以再次添加到同一父级,而 window 是视图被管理器淡出的时候。

由于淡入淡出动画不是那么快,用户可以很容易地在此期间点击按钮两次,导致管理器重新添加已经在 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);

pskink post 编辑了评论中的答案,但在要求他两次 post 作为我接受但从不这样做的答案之后,我会 post而是将其标记为已回答。

TransitionManager 有一个方法 excludeChildren 非常适合我正在寻找的东西。您可以使用 by class 类型,children 的特定视图等等。

编辑:请求添加示例

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

constraintLayout 作为目标视图的 parent,将 R.id.recyclerView 作为我不想要的 parent 的 child 视图是动画的,在这个具体的例子中就是这样。您还可以排除属于特定 class(例如 EditText)的所有 children,依此类推。

我是这样修复的:

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

它与 AutoTransition 中的代码几乎相同,如果我们不通过自定义转换,这是默认代码,但我删除了 addTransition(Fade(Fade.OUT)) 这似乎是导致碰撞。至少对我来说,动画看起来与原版非常相似。