MotionLayout: несколько кумулятивных переходов - PullRequest
0 голосов
/ 06 марта 2019

Я использую MotionLayout и пытаюсь применить серию переходов (определено в MotionScene файле). Например, Transition1 меняет положение View1, а затем Transition2 впоследствии меняет положение View2. Проблема, которую я вижу, заключается в том, что Transition2 заставляет View1 вернуться к своему первоначальному макету. Я запускаю переходы, используя вызовы transitionToState() (я также пытался явно указать начальное / конечное состояние для перехода, используя setTransition(), а затем вызывал transitionToEnd()).

Я видел комментарий в https://www.raywenderlich.com/8883-motionlayout-tutorial-for-android-getting-started, что

если вы не предоставите конечное ограничение для представления, оно будет исчезают. Это происходит потому, что библиотека не знает, какие ограничения, которые должны применяться в конце анимации

Необходимо ли также включать информацию о компоновке View1 в ConstraintSet для Transition2?

В https://github.com/googlesamples/android-ConstraintLayoutExamples/blob/master/README.md есть пример "Multi State", но похоже, что все переходы начинаются с одного базового состояния (а не "накапливаются")

Ответы [ 2 ]

1 голос
/ 08 марта 2019

Как сказал @ hoford , наборы ограничений не объединяются при каждом изменении.По-видимому, это также невозможно без использования отражения, хотя, безусловно, было бы полезно.В любом случае, вот как это сделать, используя отражение (с помощью нескольких функций расширения).

Я создал свой собственный 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)

Дайте мне знать, если это работает или есть ошибки!

1 голос
/ 06 марта 2019

Переходы не являются дельтой состояния.Они переходят от штата к штату.ConstraintSets определяют эти состояния.

ConstraintSets (в контексте MotionScene) определяют состояние, которое является базовым макетом + ваши изменения описаны в теге.

...