react-native expo 应用程序中的 Stack Navigator 问题
Stack Navigator issue in a react-native expo app
我在具有登录、注册和忘记密码屏幕的 expo 38.0 react-native 应用程序中有一些示例代码。这些屏幕之间的导航由 Stack Navigator(使用反应导航 5.x)控制,登录屏幕作为初始屏幕。
堆栈导航器在我的 android phone 上按预期工作,但在 ForgotPwdScreen 组件上按下后退按钮时出现问题。问题是在登录屏幕显示其内容后的片刻,该屏幕上的所有内容突然向下移动了几个像素。我在最后一天进行了很多研究,但似乎没有任何效果。我试过在登录屏幕的 SafeAreaView 中包装内容,但没有帮助。
但是如果我在 App.js 中包含 ForgotPwdScreen 代码,那么这个问题就不再存在了。只有当 ForgotPwdScreen 在它自己的单独文件中时才会出现此问题。
完整的代码示例位于以下小吃处:Working code for this issue
看到有关此问题的视频
这个问题只发生在 android phone 而不是 iphones.
问题 : 为什么在ForgotPwdScreen 上按下后退按钮时登录屏幕的内容在完全呈现后突然向下移动,但只有当ForgotPwdScreen 位于单独的js 文件中时?
代码文件如下。
package.json
{
"dependencies": {
"expo-status-bar": "^1.0.2",
"react-native-screens": "~2.9.0",
"@react-navigation/stack": "^5.9.1",
"react-native-reanimated": "~1.9.0",
"@react-navigation/drawer": "^5.9.1",
"@react-navigation/native": "^5.7.4",
"react-native-safe-area-context": "~3.0.7",
"@react-native-community/masked-view": "0.1.10",
"@react-native-community/async-storage": "~1.11.0"
}
}
App.js
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
KeyboardAvoidingView,
ScrollView,
StatusBar,
Keyboard,
ActivityIndicator,
Platform,
Image,
} from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import {
createStackNavigator,
TransitionSpecs,
HeaderStyleInterpolators,
CardStackStyleInterpolator,
CardStyleInterpolators
} from '@react-navigation/stack';
import LoginScreen from './components/LoginScreen'
import ForgotPwdScreen from './components/ForgotPwdScreen'
function SignUpScreen () {
/* Component state. Change someState, setEnteredSomeState and state object as per your scenario. */
const [someState, setEnteredSomeState] = useState({
state1: '',
state2: '',
state3: false,
});
return (
<View style={styles.container}>
{/* Set statusbar background color and style so it blends with the screen */}
<StatusBar backgroundColor="#fff" barStyle="dark-content" />
<Text style={styles.label}>SignUp will show here</Text>
</View>
);
}
const Stack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Login"
screenOptions={{
headerShown: false,
headerTitleAlign: 'center',
headerMode: 'screen',
}}>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="ForgotPwd"
component={ForgotPwdScreen}
options={{ headerShown: true }}
/>
<Stack.Screen
name="SignUp"
component={SignUpScreen}
options={{ headerShown: true }}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#fff',
},
scroll: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
},
inputView: {
width: '80%',
backgroundColor: '#fff',
height: 50,
marginBottom: 20,
justifyContent: 'center',
alignSelf: 'center',
textAlign: 'left',
padding: 20,
borderBottomColor: 'black',
borderBottomWidth: 1,
marginTop: -20,
},
inputText: {
height: 50,
color: 'grey',
},
loginBtn: {
width: '70%',
backgroundColor: '#F26722',
height: 50,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'center',
marginTop: 40,
marginBottom: 10,
borderWidth: 1,
borderColor: '#F26522',
},
loginText: {
color: 'white',
},
forgotText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
marginTop:20,
},
signupText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
forgotBtn: {
height: 50,
width:'100%',
marginTop:10,
},
signupBtn: {
height: 50,
width:'100%',
marginTop:20,
},
label: {
textAlign: 'center',
},
});
export default App;
ForgotPwdScreen.js
import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, ScrollView} from 'react-native';
export default function ForgotPwdScreen() {
return (
<View style={styles.container}>
{/* Set statusbar background color and style so it blends with the screen */}
<StatusBar backgroundColor="#fff" barStyle="dark-content" />
<Text style={styles.label}>ForgotPwd will show here</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
label: {
textAlign: 'center',
},
});
LoginScreen.js
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
KeyboardAvoidingView,
ScrollView,
StatusBar,
Keyboard,
ActivityIndicator,
Platform,
Image,
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
export default function LoginScreen({ route, navigation }) {
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={styles.scroll}
keyboardShouldPersistTaps="always">
<StatusBar backgroundColor="#fff" barStyle="dark-content" />
<TouchableOpacity
style={styles.forgotBtn}
onPress={() => navigation.navigate('ForgotPwd')}>
<Text style={styles.forgotText}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.signupBtn}
onPress={() => navigation.navigate('SignUp')}>
<Text style={styles.signupText}>Signup</Text>
</TouchableOpacity>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#fff',
},
scroll: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
},
forgotText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
marginTop: 20,
},
signupText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
forgotBtn: {
height: 50,
width: '100%',
marginTop: 10,
},
signupBtn: {
height: 50,
width: '100%',
marginTop: 20,
},
});
经过 2 天的尝试,我终于找到了这种奇怪行为的原因。
此问题的发生是由于 expo-status-bar
包包含在 ForgotPwdScreen.js
中。当我删除 expo-status-bar 的导入并使用 react-native 中的 StatusBar
组件时,问题就消失了。
所以,显然 expo-status-bar
存在一些问题。最好不要使用它,而是使用 react-native.
附带的默认 StatusBar
ForgotPwdScreen.js
原装进口
import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, ScrollView} from 'react-native';
更改 ForgotPwdScreen.js 中的导入解决了问题
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, ScrollView, StatusBar} from 'react-native';
我在具有登录、注册和忘记密码屏幕的 expo 38.0 react-native 应用程序中有一些示例代码。这些屏幕之间的导航由 Stack Navigator(使用反应导航 5.x)控制,登录屏幕作为初始屏幕。
堆栈导航器在我的 android phone 上按预期工作,但在 ForgotPwdScreen 组件上按下后退按钮时出现问题。问题是在登录屏幕显示其内容后的片刻,该屏幕上的所有内容突然向下移动了几个像素。我在最后一天进行了很多研究,但似乎没有任何效果。我试过在登录屏幕的 SafeAreaView 中包装内容,但没有帮助。
但是如果我在 App.js 中包含 ForgotPwdScreen 代码,那么这个问题就不再存在了。只有当 ForgotPwdScreen 在它自己的单独文件中时才会出现此问题。
完整的代码示例位于以下小吃处:Working code for this issue
看到有关此问题的视频这个问题只发生在 android phone 而不是 iphones.
问题 : 为什么在ForgotPwdScreen 上按下后退按钮时登录屏幕的内容在完全呈现后突然向下移动,但只有当ForgotPwdScreen 位于单独的js 文件中时?
代码文件如下。
package.json
{
"dependencies": {
"expo-status-bar": "^1.0.2",
"react-native-screens": "~2.9.0",
"@react-navigation/stack": "^5.9.1",
"react-native-reanimated": "~1.9.0",
"@react-navigation/drawer": "^5.9.1",
"@react-navigation/native": "^5.7.4",
"react-native-safe-area-context": "~3.0.7",
"@react-native-community/masked-view": "0.1.10",
"@react-native-community/async-storage": "~1.11.0"
}
}
App.js
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
KeyboardAvoidingView,
ScrollView,
StatusBar,
Keyboard,
ActivityIndicator,
Platform,
Image,
} from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import {
createStackNavigator,
TransitionSpecs,
HeaderStyleInterpolators,
CardStackStyleInterpolator,
CardStyleInterpolators
} from '@react-navigation/stack';
import LoginScreen from './components/LoginScreen'
import ForgotPwdScreen from './components/ForgotPwdScreen'
function SignUpScreen () {
/* Component state. Change someState, setEnteredSomeState and state object as per your scenario. */
const [someState, setEnteredSomeState] = useState({
state1: '',
state2: '',
state3: false,
});
return (
<View style={styles.container}>
{/* Set statusbar background color and style so it blends with the screen */}
<StatusBar backgroundColor="#fff" barStyle="dark-content" />
<Text style={styles.label}>SignUp will show here</Text>
</View>
);
}
const Stack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Login"
screenOptions={{
headerShown: false,
headerTitleAlign: 'center',
headerMode: 'screen',
}}>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="ForgotPwd"
component={ForgotPwdScreen}
options={{ headerShown: true }}
/>
<Stack.Screen
name="SignUp"
component={SignUpScreen}
options={{ headerShown: true }}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#fff',
},
scroll: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
},
inputView: {
width: '80%',
backgroundColor: '#fff',
height: 50,
marginBottom: 20,
justifyContent: 'center',
alignSelf: 'center',
textAlign: 'left',
padding: 20,
borderBottomColor: 'black',
borderBottomWidth: 1,
marginTop: -20,
},
inputText: {
height: 50,
color: 'grey',
},
loginBtn: {
width: '70%',
backgroundColor: '#F26722',
height: 50,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'center',
marginTop: 40,
marginBottom: 10,
borderWidth: 1,
borderColor: '#F26522',
},
loginText: {
color: 'white',
},
forgotText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
marginTop:20,
},
signupText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
forgotBtn: {
height: 50,
width:'100%',
marginTop:10,
},
signupBtn: {
height: 50,
width:'100%',
marginTop:20,
},
label: {
textAlign: 'center',
},
});
export default App;
ForgotPwdScreen.js
import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, ScrollView} from 'react-native';
export default function ForgotPwdScreen() {
return (
<View style={styles.container}>
{/* Set statusbar background color and style so it blends with the screen */}
<StatusBar backgroundColor="#fff" barStyle="dark-content" />
<Text style={styles.label}>ForgotPwd will show here</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
label: {
textAlign: 'center',
},
});
LoginScreen.js
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
KeyboardAvoidingView,
ScrollView,
StatusBar,
Keyboard,
ActivityIndicator,
Platform,
Image,
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
export default function LoginScreen({ route, navigation }) {
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={styles.scroll}
keyboardShouldPersistTaps="always">
<StatusBar backgroundColor="#fff" barStyle="dark-content" />
<TouchableOpacity
style={styles.forgotBtn}
onPress={() => navigation.navigate('ForgotPwd')}>
<Text style={styles.forgotText}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.signupBtn}
onPress={() => navigation.navigate('SignUp')}>
<Text style={styles.signupText}>Signup</Text>
</TouchableOpacity>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#fff',
},
scroll: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
},
forgotText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
marginTop: 20,
},
signupText: {
color: '#337ab7',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
forgotBtn: {
height: 50,
width: '100%',
marginTop: 10,
},
signupBtn: {
height: 50,
width: '100%',
marginTop: 20,
},
});
经过 2 天的尝试,我终于找到了这种奇怪行为的原因。
此问题的发生是由于 expo-status-bar
包包含在 ForgotPwdScreen.js
中。当我删除 expo-status-bar 的导入并使用 react-native 中的 StatusBar
组件时,问题就消失了。
所以,显然 expo-status-bar
存在一些问题。最好不要使用它,而是使用 react-native.
ForgotPwdScreen.js
原装进口import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, ScrollView} from 'react-native';
更改 ForgotPwdScreen.js 中的导入解决了问题
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, ScrollView, StatusBar} from 'react-native';