【问题标题】:Stack Navigator issue in a react-native expo appreact-native expo 应用程序中的 Stack Navigator 问题
【发布时间】:2021-01-27 10:58:53
【问题描述】:

我在 expo 38.0 react-native 应用程序中有一些示例代码,该应用程序具有登录、注册和 forgotpwd 屏幕。这些屏幕之间的导航由 Stack Navigator(使用 React Navigation 5.x)控制,登录屏幕作为初始屏幕。

堆栈导航器在我的 Android 手机上按预期工作,但是在 ForgotPwdScreen 组件上按下后退按钮时出现问题。问题是登录屏幕显示其内容后的片刻,此屏幕上的所有内容突然向下移动了几个像素。最后一天我研究了很多,但似乎没有任何效果。我曾尝试在登录屏幕的 SafeAreaView 中包装内容,但没有帮助。

但是如果我在 App.js 中包含 ForgotPwdScreen 代码,那么这个问题就不再存在了。仅当 ForgotPwdScreen 位于其自己的单独文件中时才会发生此问题。

完整代码示例在以下点心:Working code for this issue

可以在Issue of stack navigator观看有关此问题的视频

这个问题只发生在安卓手机上,而不是在iphone上。

问题 : 为什么在 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,
  },
});

【问题讨论】:

    标签: android react-native expo stack-navigator


    【解决方案1】:

    经过 2 天的尝试,我终于找到了这种奇怪行为的原因。

    由于ForgotPwdScreen.js 中包含的expo-status-bar 包而发生此问题。当我删除 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';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-15
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2017-09-04
      • 2023-01-31
      相关资源
      最近更新 更多