代码之家  ›  专栏  ›  技术社区  ›  Shadow

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

  •  1
  • Shadow  · 技术社区  · 6 年前

    我想用一个 ConstraintLayout 与随动画上下滑动的视图一起使用。 这些视图是垂直组织的,其中 RecyclerView 顶部和下面的两个其他视图:

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

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

    到目前为止,动画效果良好,但当用户点击按钮太快时,问题就会出现,导致以下错误:

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

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

    • 淡出第一个/最后一个视图 回收视图 (取决于是否启用了反向布局或从末端堆叠)
    • 从中删除该视图 回收视图
    • 降低 回收视图
    • 向上移动第一个视图

    尽管我在所有地方都指定了我可以想象的 回收视图 不应设置项目更改的动画, 过渡经理 正在覆盖它,这意味着有一个窗口将要从 回收视图 可以再次添加到同一个父级,而该窗口是管理器淡出视图时的窗口。

    由于淡入淡出动画的速度不是很快,用户可以很容易地在这段时间内按两次按钮,使管理器重新添加淡出视图,该视图已经位于 回收视图 从而在抛出上述错误时使应用程序崩溃。

    因为这是在 回收视图 我会非常好,里面没有动画,因此我想知道如何在 TransitionManager.beginDelayedTransition 只动画的直接子视图 约束布局 ,这样它就不会在 回收视图 .

    相关的文档对此没有任何影响,因此我在这里提出了这个问题;如何限制向直接子视图的转换?

    如果它可能会有帮助,我在这里包括转换管理器的片段

        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);
    
    2 回复  |  直到 6 年前
        1
  •  6
  •   Shadow    6 年前

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

    这个 TransitionManager 有一个方法 excludeChildren 这对我正在寻找的东西非常有效。可以按类类型、特定视图的子视图等使用。

    编辑:添加请求的示例

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

    constraintLayout 作为目标视图的父级 R.id.recyclerView 在这个特定的例子中,作为一个我不想被动画化的父对象的子视图。也可以排除特定类的所有子级( EditText 例如)等等。

        2
  •  2
  •   epool    6 年前

    我是这样修好的:

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

    里面的代码几乎是一样的 AutoTransition 如果不通过自定义转换,则默认值为,但我删除了 addTransition(Fade(Fade.OUT)) 那似乎是撞车的原因。动画看起来和原版非常相似,至少对我来说。