为导航抽屉添加菜单按钮出现错误

时间:2019-08-26 09:52:15

标签: react-native

我已经搜索了如何为我的react-native项目设置一个按钮以对Stackoverflow进行抽屉操作,并按照答案进行操作,但是仍然无法正常工作。有些答案,它根本行不通,但有时却给出了错误(不变违规错误)。但是打开抽屉的滑动动作正在起作用,我仍然想包括用于导航抽屉的按钮。我引用了此链接:Add hamburger button to React Native Navigation

这是我的代码,对不起,它太大了。

import React, { Component } from 'react';
import {
  StyleSheet,  Text,
  View,  TextInput,
  Button,  TouchableHighlight,
  TouchableOpacity,  Image,
  Alert,  ImageBackground,
  Platform,  YellowBox,
  Dimensions,  Keyboard,
  TouchableWithoutFeedback, AsyncStorage,
  ActivityIndicator, FlatList,
  ScrollView
} from 'react-native';
import { createStackNavigator, createAppContainer,createDrawerNavigator, DrawerToggle, DrawerNavigator, DrawerActions, StackNavigator } from "react-navigation";
import { Container, Content, ListItem, List } from "native-base";

class Hidden extends React.Component {
  render() {
    return null;
  }
}

const DismissKeyboard = ({ children }) => (
  <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
    {children}
  </TouchableWithoutFeedback>
);

class LoginView extends Component {
  static navigationOptions = {
    header: null,
  };


  constructor(props) {
    super(props);
    this.myTextInput1 = React.createRef();
    this.myTextInput2 = React.createRef();
    this.state = {
      email   : '',
      password: '',
    };
    let keys = ['email', 'password'];
    AsyncStorage.multiRemove(keys, (err) => {
      console.log('Local storage user info removed!');
    });
  }

  onClickListener = (viewId) => {
    Alert.alert("Help", "Contact Admin for "+viewId);
  }

  validateEmail = (email) => {
  var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
  };

  loginNext = ()=>{
    AsyncStorage.multiSet([
      ["email", this.state.email],
      ["password", this.state.password]
    ]);

    this.setState({
      email   : '',
      password: '',
    });

    this.myTextInput1.current.clear();
    this.myTextInput2.current.clear();

    Keyboard.dismiss();

    if (this.validateEmail(this.state.email)){
      this.props.navigation.navigate('profile');
    }
    else{
      Alert.alert('Warning','Enter proper email!')
    }
  }

  render() {


    return (
      <DismissKeyboard>
      <ImageBackground source={require('./zbg_app_1.jpg')} style={{width: '100%', height: '100%'}}>
      <View style={styles.container}>
        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/email/ultraviolet/50/3498db'}}/>
          <TextInput style={styles.inputs}
              placeholder="Email"
              keyboardType="email-address"
              underlineColorAndroid='transparent'
              onChangeText={(email) => this.setState({email})}
              ref = {this.myTextInput1}/>
        </View>

        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
          <TextInput style={styles.inputs}
              placeholder="Password"
              secureTextEntry={true}
              underlineColorAndroid='transparent'
              onChangeText={(password) => this.setState({password})}
              ref = {this.myTextInput2}/>
        </View>

        <TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress={()=>{(this.state.email != '' && this.state.password != '') ?this.loginNext():Alert.alert('Warning','Empty Field(s)!')}}>
          <Text style={styles.loginText}>Login</Text>
        </TouchableHighlight>

        <TouchableHighlight style={styles.buttonContainer} onPress={() => this.onClickListener('forgot_password')}>
            <Text>Forgot your password?</Text>
        </TouchableHighlight>


      </View>
      </ImageBackground>
      </DismissKeyboard>
    );
  }
}

class ProfileView extends Component {
  static navigationOptions = {
    headerTitle: 'Profile',
  };

  constructor(props) {
    super(props);
    this.myTextInput1 = React.createRef();
    this.state = {
      loggedEmail :'',
      loggedPassword: '',
      city:''
    }
  }

  submitNext = ()=>{

    this.myTextInput1.current.clear();

    Keyboard.dismiss();

    Alert.alert('Information',this.state.city);
    {/*AsyncStorage.setItem('city',this.state.city);

    this.setState({
      city:''
    });
    */}

  }



  render() {
    AsyncStorage.multiGet(['email', 'password']).then(data => {

      let email = data[0][1];
      let password = data[1][1];

      if (email !== null){
          this.setState({loggedEmail:email});
        }
    });
    return (

      <View style={{ flexDirection: 'column' , alignItems: 'center', justifyContent: 'center'}}>
        <View style={{ flexDirection: 'column' , marginTop: 60, alignItems: 'center', justifyContent: 'center'}}>
        <Text>{this.state.loggedEmail}</Text>

        <Button onPress={()=> this.props.navigation.navigate('login')}  title="Login Page"/>

        </View>
        {/*<View style={styles.container1}>
          <View style={styles.inputContainer}>
            <TextInput style={styles.inputs}
                placeholder="Enter city"
                underlineColorAndroid='transparent'
                onChangeText={(city) => this.setState({city})}
                ref = {this.myTextInput1}/>
          </View>


          <TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress={()=>{(this.state.city != '') ?this.submitNext():Alert.alert('Warning','Empty Field(s)!')}}>
            <Text style={styles.loginText}>Submit</Text>
          </TouchableHighlight>

        </View>*/}
      </View>

    );
  }
}

class Custom_Side_Menu extends Component {

  render() {

    return (

      <View style={styles.sideMenuContainer}>

        <Image source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2017/10/Guitar.jpg' }}
          style={styles.sideMenuProfileIcon} />

        <View style={{ width: '100%', height: 1, backgroundColor: '#e2e2e2', marginTop: 15}} />

        <View style={{width: '100%'}}>

            <View style={{flexDirection: 'row', alignItems: 'center', marginTop: 10}}>

              <Image source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/08/social.jpg' }}
              style={styles.sideMenuIcon} />

              <Text style={styles.menuText} onPress={() => { this.props.navigation.navigate('First') }} > First Activity </Text>

            </View>

            <View style={{flexDirection: 'row', alignItems: 'center', marginTop: 10}}>

              <Image source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/08/promotions.jpg' }}
              style={styles.sideMenuIcon} />

              <Text style={styles.menuText} onPress={() => { this.props.navigation.navigate('Second') }} > Second Activity </Text>

            </View>

            <View style={{flexDirection: 'row', alignItems: 'center', marginTop: 10}}>

              <Image source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/08/outbox.jpg' }}
              style={styles.sideMenuIcon} />

              <Text style={styles.menuText} onPress={() => { this.props.navigation.navigate('Third') }} > Third Activity </Text>

            </View>


       </View>

       <View style={{ width: '100%', height: 1, backgroundColor: '#e2e2e2', marginTop: 15}} />


      </View>
    );
  }
}

class Fetch extends Component{

  constructor(props){
    super(props);
    this.state ={ isLoading: true,};

  }

  componentDidMount(){
    return fetch('http://d4abf7d9.ngrok.io/opdytat003/api/login/',
    {
      method: 'POST',
      headers:{
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },


    })
      .then((response) => response.json())
      .then((responseJson) => {

        this.setState({
          isLoading: false,
          dataSource: responseJson,
        }, function(){

        });

      })
      .catch((error) =>{
        console.error(error);
      });
  }

  render(){
    console.log(this.state.dataSource)
    if(this.state.isLoading){
      return(
        <View style={{flex: 1, padding: 20}}>
          <ActivityIndicator/>
        </View>
      )
    }

    return(
      <ScrollView style={{flex: 1, paddingTop:30}}>
        {/*<FlatList
          data={this.state.dataSource}
          renderItem={({item}) => <Text>{item.title}, {item.releaseYear}</Text>}
          keyExtractor={({id}, index) => id}
        />*/}
        <Text>API => Zelthy API:</Text>

        <Text>{JSON.stringify(this.state.dataSource.next_step)}</Text>
        <Text>{JSON.stringify(this.state.dataSource.access_token)}</Text>
        <Text>{JSON.stringify(this.state.dataSource.menu)}</Text>
        <Text>{JSON.stringify(this.state.dataSource.detail)}</Text>
        <Text>{JSON.stringify(this.state.dataSource.responsecode)}</Text>
        <Text>{JSON.stringify(this.state.dataSource.refresh_token)}</Text>
      </ScrollView>
    );
  }
}

const AppLogin = createStackNavigator({
    login: {
      screen: LoginView,
    },

},
{
    initialRouteName: "login"
}
);
const AppProfile = createStackNavigator({
    profile: {
      screen: ProfileView,
    },

},

);


const Nav = createDrawerNavigator(

{
  Home: {
    screen: AppLogin,
    navigationOptions:{
      drawerLockMode: 'locked-closed',
      drawerLabel: <Hidden />
    },

  },
  Profile: {
    screen: AppProfile
  },
  Activities: {screen: Custom_Side_Menu},
  API: {screen: Fetch},
  'Sign Out': {screen: LoginView},

},

{
  contentOptions: {
    activeTintColor: 'green',
    inactiveTintColor: 'white',

  },
  drawerPosition: 'left',
  drawerWidth: 200,
  drawerBackgroundColor: 'purple',
  initialRouteName: 'Home'
}

);

export default createAppContainer(Nav);

我已经提到了Github React Native问题链接,但对我来说也无济于事。

当我在“个人档案”屏幕的StackNavigator中添加这部分代码时,我在输出以下获得此内容,但单击时无变化。

navigationOptions: ({ navigation }) => ({
      title: 'Profile',  // Title to appear in status bar
      headerLeft: <Button title='=' onPress={ () => navigation.navigate('DrawerOpen') } />
    })

截屏: enter image description here

1 个答案:

答案 0 :(得分:1)

https://reactnavigation.org/docs/en/drawer-navigator.html#drawernavigatorconfig

在DrawerNavigatorConfig中添加 contentComponent ,该菜单显示实际的侧面MenuBar,如果汉堡包从右侧滑动,则将汉堡包放在MenuBar的左上方,如果汉堡包从屏幕的左侧滑动,则将汉堡包放在MenuBar的右上方。 / p>

contentComponent 基本上是React Component,在其中显示诸如主页,个人资料,我的订单,注销等项目的列表。您可以在所有这些选项的上方角落添加汉堡包。

此外,尝试用TouchableOpacity替换Button。另外,首先尝试使用TouchableOpacity的onPress功能在控制台上记录某些内容。如果仅成功记录日志,则附加navigation.navigate(“ xyz-screen”),还请确保您的导航对象中存在导航方法。有时由于未定义的导航对象而导致错误。如果存在导航对象,请尝试使用 onPress = {navigation.openDrawer} 而不是navigation.navigate(“ DrawerOpen”)。