我正在尝试将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
中的淡入淡出视图,从而导致崩溃app抛出上述错误。
由于这是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);
答案 0 :(得分:4)
pskink在评论中发布了答案,但在两次要求他发帖作为我接受并且从不这样做的答案之后,我会发布它并将其标记为已回答。
TransitionManager
有一个方法excludeChildren
,可以完美地满足我的需求。您可以按类类型,特定视图的子项等使用。
编辑:添加请求的示例
AutoTransition autoTransition = new AutoTransition();
autoTransition.excludeChildren(R.id.recyclerView, true);
TransitionManager.beginDelayedTransition(constraintLayout, autoTransition);
constraintLayout
作为目标视图的父级,而R.id.recyclerView
是我不想要动画的父级的子视图,在这个特定示例中是。您还可以排除特定班级的所有孩子(例如EditText
),依此类推。
答案 1 :(得分:1)
我以这种方式解决了这个问题
TransitionManager.beginDelayedTransition(
constraintLayout,
TransitionSet().apply {
ordering = TransitionSet.ORDERING_SEQUENTIAL
addTransition(ChangeBounds())
addTransition(Fade(Fade.IN))
}
)
AutoTransition
内的代码几乎相同,如果我们不通过自定义转换,则这是默认代码,但我删除了似乎是导致崩溃的addTransition(Fade(Fade.OUT))
。至少对于我来说,动画看起来与原始动画非常相似。