如何指定TransitionManager.beginDelayedTransition仅影响直接子视图 [英] How to specify TransitionManager.beginDelayedTransition to affect only direct child views

查看:701
本文介绍了如何指定TransitionManager.beginDelayedTransition仅影响直接子视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to use a ConstraintLayout in conjunction with views that slide up and down with animation. These views are organized vertically, with a RecyclerView at the top and two other views stacked under it:

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

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

The animation is very simple: When a button is tapped the 1st view moves from the bottom of the container to the position you can see above, when tapped again it moves down and stays overlapped on the 2nd view. When this happens the RecyclerView at the top changes height since it is constrained to that 1st view, otherwise it would leave an empty space.

到目前为止效果很好,动画效果很好,但是当用户过快地点击按钮时会出现问题,从而导致以下错误:

So far so good and the animation is working well, but the problem arises when the user taps the button too fast, leading to the following error:

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

在调查了所发生的情况之后,我发现此问题是由于TransitionManager所引起的,我正在使用这些TransitionManager来为更改制作动画.我发现的发现很有趣,当点击按钮以将第一个视图上移(或下移,想象一下相反的步骤)时,经理正在执行以下操作:

After investigating what was going on I discovered that this problem is a consequence of the TransitionManager that I am using to animate the changes. What I discovered was interesting, when the button was tapped to move the 1st view up (or down, just imagine the opposite steps) the manager was doing the following:

  • RecyclerView中淡出第一个/最后一个视图(取决于您是否启用了反向布局或启用了从头到尾的堆栈)
  • RecyclerView
  • 删除该视图
  • 减小RecyclerView
  • 的高度
  • 向上移动第一个视图
  • Fade out the first/last view from the RecyclerView (depends on whether or not you have a reversed layout or stack from end enabled)
  • Remove that view from the RecyclerView
  • Decrease the height of the RecyclerView
  • Move the 1st view up

即使我在所有地方都指定了我可以想象的RecyclerView都不应该对项目更改进行动画处理,但TransitionManager却覆盖了它,这意味着当要删除的同一视图时有一个窗口可以再次将RecyclerView中的内容添加到同一父对象,并且该窗口是管理者逐渐淡出视图的时间.

Even though I specified in all the places I could imagine that the RecyclerView should not animate item changes, the TransitionManager was overriding it and that meant there is a window when the same view that is being about to be removed from the RecyclerView can be added again to the same parent, and that window is when the view is fading out by the manager.

由于淡入淡出动画的速度并不快,因此用户可以在这段时间内轻按两次按钮,从而使管理者重新添加已经位于RecyclerView中的淡入淡出视图,从而导致应用程序崩溃,抛出上述错误.

Since the fade animation is not that fast, a user can very easily tap the button twice during that time, causing the manager to re-add the fading view, which is already in the RecyclerView and thus crashing the app while throwing the above error.

由于这是在RecyclerView内部引起的问题,所以我在其中没有任何动画就可以了,因为这个原因,我想知道如何在TransitionManager.beginDelayedTransition中指定仅对...的直接子视图进行动画处理ConstraintLayout,这样就不会为RecyclerView内部的视图设置动画.

Since this is an issue caused inside the RecyclerView I would be perfectly fine with no animations inside it and for that reason I would like to know how can I specify in the TransitionManager.beginDelayedTransition to only animate the direct child views of the ConstraintLayout, this way it will not animate the views inside the RecyclerView.

相关文档对此没有任何帮助,因此我在此提出这个问题.如何限制过渡到直接子视图?

The related documentation does not shine anything over this, so I present here this question; How can I restrict the transition to direct child views?

如果有帮助的话,我在此处包括过渡管理器的代码段

In case it might be helpful I include here the snippet of the transition manager

    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在评论中发布了答案,但在两次要求他发布作为我接受但从未做过的答案之后,我将其发布而是将其标记为已回答.

pskink posted the answer in the comments, but after asking twice for him to post as an answer for me to accept and never doing it, I'll post it instead and mark this as answered.

TransitionManager的方法excludeChildren可以完美地满足我的需求.您可以按班级类型,特定视图的子级等来使用.

The TransitionManager had a method excludeChildren that works perfectly for what I was looking for. You can use by class types, children of a specific view and so on.

请求添加示例

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

使用constraintLayout作为目标视图的父级,而R.id.recyclerView是我不想对其进行动画处理的父级的子级视图,在这个特定示例中就是这样.您还可以排除所有属于特定类别的孩子(例如,EditText),等等.

With constraintLayout as the parent of the target view and R.id.recyclerView being a child view of that parent that I don't want to be animated, in this specific example that is. You can also exclude all children that are of a specific class (EditText for example) and so on.

这篇关于如何指定TransitionManager.beginDelayedTransition仅影响直接子视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆