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

Попробуйте способ создания композиций.
Jetpack Compose — рекомендуемый набор инструментов для создания пользовательского интерфейса для Android. Узнайте, как добавлять анимации в Compose.

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

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

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

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

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

Котлин

class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

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

}

Java

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 , в котором вы можете хранить нужные значения представления. В вашей реализации получите эти значения свойств и передайте их обратно во фреймворк, сохранив их в 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
    }

    ...

}

Java

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)
}

Java

@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 . Дополнительную информацию об аниматорах свойств см. в разделе «Анимация свойств» .

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

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