如何指定TransitionManager.beginDelayedTransition仅影响直接子视图
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何指定TransitionManager.beginDelayedTransition仅影响直接子视图相关的知识,希望对你有一定的参考价值。
我正在尝试将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);
pskink在评论中发布了答案,但在两次要求他发布作为我接受的答案并且从未这样做之后,我会发布它并将其标记为已回答。
TransitionManager
有一个方法excludeChildren
,完美的工作,我正在寻找。您可以按类类型,特定视图的子项等使用。
编辑:添加请求的示例
AutoTransition autoTransition = new AutoTransition();
autoTransition.excludeChildren(R.id.recyclerView, true);
TransitionManager.beginDelayedTransition(constraintLayout, autoTransition);
使用constraintLayout
作为目标视图的父级,R.id.recyclerView
是我不想要动画的父级的子视图,在这个具体示例中是。您还可以排除特定类的所有子项(例如EditText
),依此类推。
我这样修理它:
TransitionManager.beginDelayedTransition(
constraintLayout,
TransitionSet().apply {
ordering = TransitionSet.ORDERING_SEQUENTIAL
addTransition(ChangeBounds())
addTransition(Fade(Fade.IN))
}
)
它几乎与AutoTransition
中的代码相同,如果我们不通过自定义转换,它是默认代码,但我删除了似乎是崩溃原因的addTransition(Fade(Fade.OUT))
。至少对我而言,动画看起来与原作非常相似。
以上是关于如何指定TransitionManager.beginDelayedTransition仅影响直接子视图的主要内容,如果未能解决你的问题,请参考以下文章