Создайте собственную анимацию перехода

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

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

На этой странице вы узнаете, как захватывать значения свойств и создавать анимацию для создания пользовательских переходов.

Расширить класс перехода

Чтобы создать собственный переход, добавьте в проект класс, который расширяет класс Transition и переопределяет функции, показанные в следующем фрагменте:

Котлин

class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {}

}

Ява

public class CustomTransition extends Transition {

    @Override
    public void captureStartValues(TransitionValues values) {}

    @Override
    public void captureEndValues(TransitionValues values) {}

    @Override
    public Animator createAnimator(ViewGroup sceneRoot,
                                   TransitionValues startValues,
                                   TransitionValues endValues) {}
}

В следующих разделах объясняется, как переопределить эти функции.

Захват значений свойств представления

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

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

Зафиксируйте начальные значения

Чтобы передать начальные значения представления в платформу, реализуйте функцию captureStartValues(transitionValues) . Платформа вызывает эту функцию для каждого представления начальной сцены. Аргументом функции является объект TransitionValues , содержащий ссылку на представление и экземпляр Map , в котором вы можете хранить нужные значения представления. В вашей реализации извлеките эти значения свойств и передайте их обратно в платформу, сохранив на карте.

Чтобы гарантировать, что ключ значения свойства не конфликтует с другими ключами TransitionValues , используйте следующую схему именования:

package_name:transition_name:property_name

В следующем фрагменте показана реализация функции captureStartValues() :

Котлин

class CustomTransition : Transition() {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private val PROPNAME_BACKGROUND = "com.example.android.customtransition:CustomTransition:background"

    override fun captureStartValues(transitionValues: TransitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues)
    }

    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private fun captureValues(transitionValues: TransitionValues) {
        // Get a reference to the view
        val view = transitionValues.view
        // Store its background property in the values map
        transitionValues.values[PROPNAME_BACKGROUND] = view.background
    }

    ...

}

Ява

public class CustomTransition extends Transition {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private static final String PROPNAME_BACKGROUND =
            "com.example.android.customtransition:CustomTransition:background";

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues);
    }


    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private void captureValues(TransitionValues transitionValues) {
        // Get a reference to the view
        View view = transitionValues.view;
        // Store its background property in the values map
        transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
    }
    ...
}

Зафиксировать конечные значения

Платформа вызывает функцию captureEndValues(TransitionValues) один раз для каждого целевого представления в конечной сцене. Во всем остальном captureEndValues() работает так же, как captureStartValues() .

В следующем фрагменте кода показана реализация функции captureEndValues() :

Котлин

override fun captureEndValues(transitionValues: TransitionValues) {
    captureValues(transitionValues)
}

Ява

@Override
public void captureEndValues(TransitionValues transitionValues) {
    captureValues(transitionValues);
}

В этом примере функции captureStartValues() и captureEndValues() вызывают captureValues() для получения и сохранения значений. Свойство представления, которое получает captureValues() одинаково, но имеет разные значения в начальной и конечной сценах. Платформа поддерживает отдельные карты для начального и конечного состояний представления.

Создайте собственного аниматора

Чтобы анимировать изменения представления между его состоянием в начальной сцене и состоянием в конечной сцене, предоставьте аниматор, переопределив функцию createAnimator() . Когда платформа вызывает эту функцию, она передает корневое представление сцены и объекты TransitionValues , которые содержат записанные вами начальные и конечные значения.

Количество вызовов функции createAnimator() платформой зависит от изменений, происходящих между начальной и конечной сценами.

Например, рассмотрим анимацию затухания или появления, реализованную как пользовательский переход. Если начальная сцена имеет пять целей, две из которых удалены из конечной сцены, а конечная сцена имеет три цели из начальной сцены плюс новую цель, то платформа вызывает createAnimator() шесть раз. Три вызова анимируют исчезновение и появление целей, которые остаются в обоих объектах сцены. Еще два вызова анимируют затухание целей, удаленных из финальной сцены. Один вызов анимирует появление новой цели в финальной сцене.

Для целевых представлений, которые существуют как в начальной, так и в конечной сценах, платформа предоставляет объект TransitionValues ​​как для startValues , так и для аргументов endValues . Для целевых представлений, которые существуют только в начальной или конечной сцене, платформа предоставляет объект TransitionValues ​​для соответствующего аргумента и null для другого.

Чтобы реализовать функцию createAnimator(ViewGroup, TransitionValues, TransitionValues) при создании пользовательского перехода, используйте полученные значения свойств представления, чтобы создать объект Animator и вернуть его в платформу. Пример реализации см. в классе ChangeColor в примере CustomTransition . Дополнительные сведения об аниматорах свойств см. в разделе Анимация свойств .

Применить пользовательский переход

Пользовательские переходы работают так же, как встроенные переходы. Вы можете применить пользовательский переход с помощью менеджера переходов, как описано в разделе «Применение перехода» .