1

我正在使用MotionLayout并尝试应用一系列转换(在MotionScene文件中定义)。例如,Transition1 改变 View1 的位置,然后 Transition2 随后改变 View2 的位置。我看到的问题是 Transition2 导致 View1 恢复到原来的布局。我正在使用调用来触发转换transitionToState()(我还尝试使用setTransition()然后调用显式提供转换的开始/结束状态transitionToEnd())。

我在https://www.raywenderlich.com/8883-motionlayout-tutorial-for-android-getting-started中看到了评论

如果您不为视图提供结束约束,它将消失。发生这种情况是因为库不知道它应该在动画结束时应用哪些约束

是否还需要在ConstraintSetTransition2 中包含有关 View1 布局的信息?

https://github.com/googlesamples/android-ConstraintLayoutExamples/blob/master/README.md中有一个“多状态”示例,但看起来包含的转换都从单个基本状态开始(而不是“累积”)

4

2 回答 2

2

转换不是状态的增量。他们从一个州到另一个州。ConstraintSets 定义了这些状态。

ConstraintSets(在 MotionScene 的上下文中)定义了一个状态,即基本布局 + 标签中描述的更改。

于 2019-03-06T16:47:53.363 回答
2

正如@hoford所说,ConstraintSet 每次更改时都不会合并。显然,如果不使用反射,这也是不可能的,尽管它肯定很有用。无论如何,这里是如何使用反射(通过一些扩展函数)来做到这一点。

我确实创建了自己的TransitionListener基类来提供支持注释和可读的值名称。扩展功能可以在这里找到。

您可以做的是合并两者ConstraintSets,然后改变endConstraintSet可以通过以下方式获得的内容TransitionListener#onTransitionChange

class AccumulativeTransitionListener: TransitionListener() {

        var didApplyConstraintSet = false

        override fun onTransitionChange(view: MotionLayout, @IdRes startConstraintSetId: Int, @IdRes endConstraintSetId: Int, progress: Float) {
            if (!didApplyConstraintSet) {
                // Let's retrieve our ConstraintSets first
                val startConstraintSet = view.getConstraintSet(startConstraintSetId)
                val endConstraintSet = view.getConstraintSet(endConstraintSetId)
                // Merge them (using an extension function)
                val mergedConstraintSet = startConstraintSet + endConstraintSet
                // Clear + Set them
                endConstraintSet.setConstraints(mergedConstraintSet)
                didApplyConstraintSet = true
            }
        }

        override fun onTransitionCompleted(view: MotionLayout, @IdRes constraintSetId: Int) {
            didApplyConstraintSet = false
        }

    }

ConstraintSets要在每次TransitionListener#onTransitionChange调用时不合并和应用,有一个简单的辅助变量。

最后,您必须将侦听器附加到您的MotionLayout

val accumulativeListener = AccumulativeTransitionListener()
motionLayout.setTransitionListener(accumulativeListener)

让我知道这是否有效或是否有任何错误!

于 2019-03-07T22:21:42.580 回答