Анимированный экран с React Navigation - PullRequest
0 голосов
/ 14 ноября 2018

Я разрабатываю приложение React Native, которое использует React Navigation управлять маршрутизацией между экранами.

Я знаю, читая Реактивную навигационную документацию и просматривая это видео на Egghead.io (настоятельно рекомендуется), в котором можно определить собственные анимации для переходов между экранами, пропускающими свойство transitionConfig до StackNavigator.

Например, следующий код определяет слайд слева анимацию, которая в основном является зеркалом push-анимации iOS по умолчанию:

const TransitionConfig = () => ({
    screenInterpolator: ({ layout, position, scene }) => {
        const { index } = scene
        const { initWidth } = layout

        const translateX = position.interpolate({
            inputRange: [index - 1, index, index + 1],
            outputRange: [-initWidth, 0, 0],
        })

        return {
            transform: [{ translateX }],
        }
    }
})

const MyNavigator = createStackNavigator(
    {
        A: {screen: ScreenA},
        B: {screen: ScreenB},
    },
    { transitionConfig: TransitionConfig }
)

Учитывая приведенный выше код и тот факт, что мы перемещаемся с экрана A на экран B, тело функции screenInterpolator в основном описывает анимацию, которой экран B должен следовать , когда он появится (оно исчезает, когда исчезает). В этом случае код говорит о переводе экрана B вдоль оси X для достижения слайда в эффекте .

Можно ли также определить анимацию для экрана, который исчезает (экран A в нашем случае)? Я хотел бы определить что-то вроде этого:

  • B должно появиться скользя слева направо
  • A должен исчезнуть скользя сверху вниз

1 Ответ

0 голосов
/ 15 ноября 2018

Я нашел ответ сам, надеюсь, кто-нибудь поможет в будущем.

Я ошибался, предполагая, что screenInterpolator описывает только поведение экрана B, потому что фактически описывает анимацию как A, так и B. Или, что еще лучше, это функция interpolate с inputRange и outputRange, которая позволяет описывать анимацию как для входа (B), так и для выхода (A) экрана.

Давайте ближе посмотрим на этот фрагмент, помня, что функция interpolate просто создает ассоциацию 1-1 между значениями inputRange и outputRange (более подробное объяснение здесь ).

const { index } = scene

const translateX = position.interpolate({
    inputRange:  [index - 1, index, index + 1],
    outputRange: [-initWidth, 0, 0],
})

Допущения:

  • B и A - экраны
  • мы движемся от A до B
  • width(B) = width(A) = 320
  • width(deviceScreen) = 320
  • initWidth = 320

Объяснение

  • index-1 представляет экран, который должен появиться (экран B), и он сопоставлен с -initWidth. При этом мы говорим, что экран, который должен появиться (screen B), должен быть переведен в X (относительно области просмотра) значения, равного его ширине. Таким образом, анимация запускается с X = 320 (т.е. за пределами экрана)
  • index представляет экран, который должен появиться, но один раз появился (все еще экран B). Сопоставляя его с 0, мы говорим, что экран B после его появления должен быть в положении X = 0
  • index + 1 представляет экран, который исчезнет. Это то, что привело меня к ошибке. В начале я думал, что это все еще и только экран B, но только когда он исчез бы из-за навигации, подобной B->C. Однако, с нашей A->B точки зрения, именно экран A исчезнет! Таким образом, обе линии мышления верны, это все о взглядах на вещи с другой точки зрения. Таким образом, сопоставляя index+1 с 0, мы говорим, что экран A должен оставаться на X=0, когда он исчезнет (т.е. когда B появится)

Результат

Это анимация, реализованная с помощью кода выше. Как видите, экран A остается там, где он есть из-за ассоциации index+1 <-> 0 (без перевода, поэтому нет анимации для экрана A).

Description here

Если мы изменим ассоциацию index+1 на index+1 <-> -initWidth, то экран A также будет переведен и, следовательно, анимирован:)

const translateX = position.interpolate({
  inputRange:  [index - 1, index, index + 1],
  outputRange: [initWidth, 0, -initWidth],
})

enter image description here


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...