import {Animated, Easing, Platform} from 'react-native';
import CardStackStyleInterpolator from './CardStackStyleInterpolator';
import * as ReactNativeFeatures from '../../utils/ReactNativeFeatures';
/**
* 根据不同平台上的缺省行为的不同,为iOS或者Android定义不同的屏幕过渡动画设置,
* 可以将每个屏幕过渡动画设置抽象理解为定义的一个类 TransitionConfig, 下面
* 给出了一个这样的实例方便理解 :
* {
* transitionSpec : { // 屏幕过渡动画规格定义
* duration: 500,
* easing: Easing.bezier(0.2833, 0.99, 0.31833, 0.99),
* timing: Animated.timing,
* },
* screenInterpolator : { // 屏幕切换插值器
* CardStackStyleInterpolator.forVertical,
* },
* containerStyle : { // 此属性在该文件中仅针对iOS平台使用,针对Android平台没有使用
* backgroundColor: '#000',
* }
* }
**/
let IOSTransitionSpec;
if (ReactNativeFeatures.supportsImprovedSpringAnimation()) {
// These are the exact values from UINavigationController's animation configuration
IOSTransitionSpec = {
timing: Animated.spring,
stiffness: 1000,
damping: 500,
mass: 3,
};
} else {
// This is an approximation of the IOS spring animation using a derived bezier curve
IOSTransitionSpec = {
duration: 500,
easing: Easing.bezier(0.2833, 0.99, 0.31833, 0.99),
timing: Animated.timing,
};
}
// Standard iOS navigation transition
const SlideFromRightIOS = {
transitionSpec: IOSTransitionSpec,
screenInterpolator: CardStackStyleInterpolator.forHorizontal,
containerStyle: {
backgroundColor: '#000',
},
};
// Standard iOS navigation transition for modals
const ModalSlideFromBottomIOS = {
transitionSpec: IOSTransitionSpec,
screenInterpolator: CardStackStyleInterpolator.forVertical,
containerStyle: {
backgroundColor: '#000',
},
};
// Standard Android navigation transition when opening an Activity
// 安卓平台上出现一个新屏幕时缺省使用的过渡方式
const FadeInFromBottomAndroid = {
// http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/res/res/anim/activity_open_enter.xml
transitionSpec: {
duration: 350, // 安卓平台上,修改此值,或者覆盖此值,可以对屏幕出现动画进行加速或者减速
easing: Easing.out(Easing.poly(5)), // decelerate
timing: Animated.timing,
},
screenInterpolator: CardStackStyleInterpolator.forFadeFromBottomAndroid,
};
// Standard Android navigation transition when closing an Activity
// 安卓平台上关闭一个新屏幕时缺省使用的过渡方式 (比如返回)
const FadeOutToBottomAndroid = {
// http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/res/res/anim/activity_close_exit.xml
transitionSpec: {
duration: 230, // 安卓平台上,修改此值,或者覆盖此值,可以对屏幕关闭动画进行加速或者减速
easing: Easing.in(Easing.poly(4)), // accelerate
timing: Animated.timing,
},
screenInterpolator: CardStackStyleInterpolator.forFadeFromBottomAndroid,
};
/**
* 缺省屏幕切换过渡动画配置,没有考虑开发人员的设置,使用react-navigation预定义配置
* @param transitionProps
* @param prevTransitionProps
* @param isModal
* @returns {*}
*/
function defaultTransitionConfig(
// props for the new screen
transitionProps,
// props for the old screen
prevTransitionProps,
// whether we're animating in/out a modal screen
isModal
) {
if (Platform.OS === 'android') {
// Use the default Android animation no matter if the screen is a modal.
// Android doesn't have full-screen modals like iOS does, it has dialogs.
if (
prevTransitionProps &&
transitionProps.index < prevTransitionProps.index
) {
// Navigating back to the previous screen
return FadeOutToBottomAndroid;
}
return FadeInFromBottomAndroid;
}
// iOS and other platforms
if (isModal) {
return ModalSlideFromBottomIOS;
}
return SlideFromRightIOS;
}
/**
* 构建和返回屏幕切换过渡动画配置,基于缺省屏幕切换过渡动画配置,考虑了开发人员的自定义设置
* @param transitionConfigurer 开发人员指定的设置函数,函数签名如下:
* func(transitionProps, prevTransitionProps, isModal):TransitionConfig
* @param transitionProps
* @param prevTransitionProps
* @param isModal
*/
function getTransitionConfig(
transitionConfigurer,
// props for the new screen
transitionProps,
// props for the old screen
prevTransitionProps,
isModal
) {
// 先基于 transitionProps ,prevTransitionProps ,isModal 构建缺省配置对象defaultConfig
const defaultConfig = defaultTransitionConfig(
transitionProps,
prevTransitionProps,
isModal
);
if (transitionConfigurer) {
// 如果指定了配置器函数 transitionConfigurer ,使用 transitionConfigurer 构建一个配置对象,
// 并将该配置对象覆盖到上面创建的缺省配置对象 defaultConfig 上,然会合并后的配置对象
return {
...defaultConfig,
...transitionConfigurer(transitionProps, prevTransitionProps, isModal),
};
}
// 如果没有指定配置器函数 transitionConfigurer,直接返回缺省配置对象 defaultConfig
return defaultConfig;
}
export default {
defaultTransitionConfig,
getTransitionConfig,
};
React Navigation源代码阅读 : views/CardStack/TransitionConfigs.js
最新推荐文章于 2023-09-13 15:47:22 发布