我正在使用 React Navigation 和 React Native Vision Camera 开发移动应用程序。
我正在使用本机堆栈并将动画添加到每个
Stack.Screen
。
<Stack.Screen
...
options={{animation: 'slide_from_right',...}}
/>
它们运行良好,直到我将用户从
ScanScreen
导航回来,其中包含反应本机视觉相机组件。
我的工作流程是
Home -> Scan -> Result -> back to Home
。
当我导航到
ScanScreen
时,动画正在工作,但如果我在goBack()
中调用ScanScreen
,或在popToTop()
中调用ResultScreen
,动画就会消失,应用程序看起来有点卡住。
这是我的代码
ScanScreen
const ScanScreen = ({route, navigation}) => {
const {locations} = route.params;
// permission
const {hasPermission, requestPermission} = useCameraPermission();
// if camera page is active
const isFocussed = useIsFocused();
const isForeground = useIsForeground();
const isActive = isFocussed && isForeground;
// camera torch control
const [torch, setTorch] = useState('off');
// get device
const device = useCameraDevice('back');
// inititalization
const [isCameraInitialized, setIsCameraInitialized] = useState(false);
const onInitialized = useCallback(() => {
console.log('Camera initialized!');
setIsCameraInitialized(true);
}, []);
const codeScanner = useCodeScanner({
codeTypes: ['qr', 'ean-13'],
onCodeScanned: codes => {
onQRCodeScan({codes});
},
});
useFocusEffect(
useCallback(() => {
if (!hasPermission) {
requestPermission();
}
return () => {
// setIsCameraReady(false);
};
}, []),
);
{device != null && (
<Camera
style={{flex: 1}}
device={device}
isActive={isActive}
onInitialized={onInitialized}
codeScanner={codeScanner}
torch={torch}
/>
)}
})
我在想视觉相机是否太重了?或者也许我正在处理错误的生命周期。我还没有在IOS上尝试过。
我尝试在离开页面之前停用相机,但是在我可以之后,transitionStart 没有被触发
goBack()
React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionStart', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
您可以自己处理这个问题
Stack.Navigator
您不应该在每个屏幕上使用。
喜欢:
<Stack.Navigator initialRouteName="Tabs" screenOptions={screenOptions}>
<Stack.Screen
name={Route.SPECS_FEATURES}
component={SpecAndFeatures}
options={{headerShown: false, gestureEnabled: false}}
/>
</Stack.Navigator>
屏幕选项
const screenOptions = {
cardStyle: {backgroundColor: colors.background, opacity: 1},
headerShadowVisible: false,
headerBackTitleVisible: false,
headerTitleAlign: 'center',
gestureDirection: 'horizontal',
gestureEnabled: false,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
headerTitleStyle: {color: 'white', justifyContent: 'center'},
transitionSpec: {open: config,close: closeConfig},
};
我的配置
const config = {
animation: 'spring',
config: {
stiffness: 1000,
damping: 100,
mass: 3,
overshootClamping: false,
restDisplacementThreshold: 0.01,
restSpeedThreshold: 0.01,
},
};
我的closeConfig:
const closeConfig = {
animation: 'timing',
config: {
duration: 400,
stiffness: 1000,
damping: 500,
mass: 100,
overshootClamping: false,
restDisplacementThreshold: 0.5,
restSpeedThreshold: 0.5,
},
};
如果您想更改导航动画样式,您应该在
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS
中进行更改,它提供了许多您想要的默认动画,您也可以在 config 或 closeConfig 中更新以更改动画样式。
了解更多详情,您可以访问CardStyleInterpolators