MotionLayout несколько переходов

Прежде всего, я использую androidx.constraintlayout: constraintlayout: 2.0.0-beta1, поскольку beta2 портит множество макетов в нашем приложении.

Я пытался заставить MotionLayout воспроизводить два разных перехода при разных обстоятельствах:

1) При нажатии на определенный элемент я хочу, чтобы он разворачивался и сворачивался; 2) При прокрутке идея заключалась в том, чтобы другой элемент сворачивался и расширялся (аналогично сворачивающейся панели инструментов).

После некоторого исследования я обнаружил, что MotionLayout не принимает более одного тега Transition внутри своего layoutDescription (он загружает только первый из найденных). Итак, чтобы моя реализация работала, я сделал это так:

Внутри моего MotionScene у меня есть только прокручиваемый элемент Transition с обоими его ConstraintSets. Я также определяю необходимые ConstraintSets для анимации щелчка.

<Transition
    android:id="@+id/scroll_transition"
    app:constraintSetStart="@id/notifications_expanded"
    app:constraintSetEnd="@id/notifications_collapsed">

    <OnSwipe
        app:dragDirection="dragUp"
        app:touchAnchorId="@id/swiperefresh_layout"
        app:touchAnchorSide="top"
        app:moveWhenScrollAtTop="true"/>

</Transition>

<ConstraintSet android:id="@+id/notifications_expanded">
    <Constraint android:id="@id/notifications"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_info_container"
        app:layout_constraintEnd_toEndOf="parent"/>
</ConstraintSet>

<ConstraintSet android:id="@+id/notifications_collapsed">
    <Constraint android:id="@id/notifications"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/header_info_container"
        app:layout_constraintEnd_toEndOf="parent"/>
</ConstraintSet>

<ConstraintSet android:id="@+id/header_collapsed">

    <Constraint android:id="@id/header_info_container"
        android:visibility="gone"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_layout"
        app:layout_constraintEnd_toEndOf="parent"/>

</ConstraintSet>

<ConstraintSet android:id="@+id/header_expanded">

    <Constraint android:id="@id/header_info_container"
        android:visibility="visible"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_layout"
        app:layout_constraintEnd_toEndOf="parent"/>

</ConstraintSet>

В моем макете xml я установил layoutDescription;

<androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/motion_layout"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutDescription="@xml/transitions">

Прокрутка Transition работает, как и ожидалось, безупречно. Чтобы анимация щелчка действительно работала, я вызываю ее вручную:

if (headerInfoContainer.getVisibility() == View.VISIBLE) {
    motionLayout.setTransition(R.id.header_expanded, R.id.header_collapsed);
    motionLayout.setTransitionDuration(300);
    motionLayout.transitionToEnd();
} else {
    motionLayout.setTransition(R.id.header_collapsed, R.id.header_expanded);
    motionLayout.setTransitionDuration(300);
    motionLayout.transitionToEnd();
}

Однако после этого фрагмента прокрутка перестает работать. Я подозреваю, что он был отключен, но я не могу найти, как вернуть его, как было раньше. Не помогает и отсутствие документации.

Заранее спасибо!


person UnaDeKalamares    schedule 04.10.2019    source источник
comment
Можете ли вы добавить весь макет xml, чтобы я мог видеть, где где находятся представления? Возможно, это удастся сделать с помощью двух MotionLayout.   -  person kjanderson2    schedule 17.01.2020


Ответы (1)


Я знаю, что это старый пост, но я постараюсь ответить для других, у которых может быть такая же проблема. На самом деле, да, в MotionScene может быть более одного перехода, но они будут работать только по одному за раз. Возможно, я не совсем понимаю, что вам нужно, но если вы хотите, чтобы другие представления внутри вашего заголовка анимировались, пока ваш заголовок сворачивается / расширяется, вам нужно установить их свойства Constraint внутри вашего ConstraintSet. Помните, что ConstraintSet подобен состоянию ваших представлений, он переходит из одного состояния в другое, поэтому для каждого представления, которое необходимо изменить в конкретном наборе, вам необходимо установить свойства новых представлений с помощью ConstraintSet. Что-то вроде:

   <Transition
    android:id="@+id/scroll_transition"
    app:constraintSetStart="@id/notifications_expanded"
    app:constraintSetEnd="@id/notifications_collapsed">

    <OnSwipe
        app:dragDirection="dragUp"
        app:touchAnchorId="@id/swiperefresh_layout"
        app:touchAnchorSide="top"
        app:moveWhenScrollAtTop="true"/>

</Transition>

<ConstraintSet android:id="@+id/notifications_expanded">
    ... How your views should change from default layout when getting on this state
</ConstraintSet>

<ConstraintSet android:id="@+id/notifications_collapsed">
    ... How your views should change from default layout when getting on this state
</ConstraintSet>

В теге <Transition> вы указываете MotionScene, что такое начальное и конечное состояние.

person Rodrigo Salomao    schedule 11.11.2020