React-Navigation学习笔记

  1. 如何跳转到一个新的页面?
this.props.navigation.push(routerName)
  1. 如何返回之前的页面?
this.props.navigation.goBack()
  1. 如何在页面之间传递参数?
this.props.navigation.push('Discovery',{
     id:1111,
     name:'哈哈哈'
})
  1. 如何在新页面接收传递过来的参数?
	//使用getParam()方法
	const { navigation } = this.props;
	const itemId = navigation.getParam('id', '参数没有的时候默认值'); //1111
	const itemName = navigation.getParam('name', '没有的时候默认值'); //哈哈哈
	
	//直接获取
	this.props.navigation.state.params //存放了所有传递过来的路由参数
  1. 如何修改默认的灰色导航,自定义导航栏样式?
	//静态在每个页面视图设置title
    static navigationOptions = {
       title: 'Home',
    };
    // 注意:默认情况下使用平台约定,因此在iOS上标题将居中,在Android上它将是左对齐的。


	//在导航中使用上个页面传入的params
	static navigationOptions = ({ navigation }) => {
        return {
          title: navigation.getParam('name', 'New Screen Title'), //哈哈哈
        };
    };

	//新视图中更新params
	this.props.navigation.setParams({name: '新的页面Title'}) // 新的页面Title

	//调整标题的样式
    //headerStyle,headerTintColor,和headerTitleStyle
    
	static navigationOptions = {
	    title: 'Home',
	    headerStyle: {
	      backgroundColor: '#f4511e',
	    },
	    headerTintColor: '#fff',
	    headerTitleStyle: {
	      fontWeight: 'bold',
	    },
	};

	//默认情况下在单个页面设置的样式只会在该页面显示,返回上一个页面 就会显示默认的样式 灰色 如果每个页面样式比较统一 可以在createStackNavigator事件添加

	const RootStack = createStackNavigator(
	  {
	    Home: HomeScreen,
	    Discovery: DiscoveryScreen,
	  },
	  {
	    initialRouteName: 'Home',
	    navigationOptions: {
	      headerStyle: {
	        backgroundColor: '#f4511e',
	      },
	      headerTintColor: '#fff',
	      headerTitleStyle: {
	        fontWeight: 'bold',
	      },
	    },
	  }

	//自定义组件替换默认导航(注意:自定义组件的话需要去适配安卓,苹果和iphoneX 否则显示会异常)
	class LogoTitle extends React.Component {
	    render() {
	        return (
	            <Image
	                source={require('../assets/user.jpg')}
	                style={{ width: 30, height: 30 }}
	            />
	        );
	    }
	}
	
	static navigationOptions = {
       header:<LogoTitle />
    };
);
  1. 如何使用自定义按钮覆盖原始按钮?
	//对应参数为:标题  左侧按钮  右侧按钮  (注意:自定义按钮需要自己添加事件)
	static navigationOptions = {
	    headerTitle: <LogoTitle />,
	    headerLeft:<BackButton/>
	    headerRight: (
	      <Button
	        onPress={() => console.log('right button!')}
	        title="Info"
	        color="#fff"
	      />
	    ),
	};
  1. 如何给自定义按钮加上处理事件?
import Icon from 'react-native-vector-icons/Entypo';
	class BackButton extends React.Component {
	    render() {
	        return (
	            <TouchableOpacity onPress={_ => this.props.navigation.goBack()}>
	                <Icon
	                    style={{ paddingLeft: 8, color: '#FFF' }}
	                    name="chevron-thin-left"
	                    size={18}
	                />
	            </TouchableOpacity>
	        );
	    }
}

export default class Discovery extends Component {
    static navigationOptions = ({ navigation }) => {
        return {
            title: 'Discovery',
            headerStyle: {
                backgroundColor: '#f4511e',
            },
            headerTintColor: '#fff',
            headerTitleStyle: {
                fontWeight: 'bold',
            },
            headerLeft: <BackButton navigation={navigation} />,
            headerRight: (
                <Button
                    onPress={navigation.getParam('rightButtonClick')}
                    title="Info"
                    color="#fff"
                />
            ),
        }
    };
    componentDidMount = () => {
      this.props.navigation.setParams({
        rightButtonClick:this._rightClick
      })
    }
    
    _rightClick=()=>{
        alert('click right button')
    }
  1. 如何修改导航左侧的默认返回按钮?
  //(规则:如果要在页面的返回按钮文本修改为自定义文本,需要去前置页面A添加而不是在该页面B修改,优先显示headerBackTitle,当该文本显示长度过长导致不能显示的时候,会显示headerTruncatedBackTitle配置的文本)
  
  // 页面A
  static navigationOptions = {
    title: 'Home',
    headerStyle: {
      backgroundColor: '#f4511e',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold',
    },
    headerBackTitle:'我是上一个页面的文本我很长很长',          
    headerTruncatedBackTitle:'Back',
  };
  
  //页面B
  static navigationOptions = ({ navigation }) => {
      return {
          title: 'Discovery',
          headerStyle: {
              backgroundColor: '#f4511e',
          },
          headerTintColor: '#fff',
          headerTitleStyle: {
              fontWeight: 'bold',
          },
        }
 };
  1. 如何展示那些全屏页面 即无需头部导航组件(例如登录页)?

    要显示全屏页面需要去修改默认的createStackNavigator

	//正常需要头组件的页面
	const MainStack = createStackNavigator({
	    Home: HomeScreen,
	    Discovery:{
	        screen:DiscoveryScreen
	    }
	},
    {
        initialRouteName: 'Home',
    });
	
	//根路由,把其他需要全屏的页面单独拎出来
	const RootStack = createStackNavigator(
	    {
	        Main:{
	            screen:MainStack
	        },
	        Login:{
	            screen:LoginScreen
	        }
	    },
	    {
	        mode:'modal', // card || modal
	        headerMode:'none'
	});
	
	export default class App extends React.Component {
	    render() {
	      return <RootStack />;
	    }
	}
  1. 如何添加tab选项卡导航?
	import React from 'react';
	import { Text, View } from 'react-native';
	import { createBottomTabNavigator } from 'react-navigation';
	
	class HomeScreen extends React.Component {
	  render() {
	    return (
	      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
	        <Text>Home!</Text>
	      </View>
	    );
	  }
	}
	
	class SettingsScreen extends React.Component {
	  render() {
	    return (
	      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
	        <Text>Settings!</Text>
	      </View>
	    );
	  }
	}
	
	export default createBottomTabNavigator({
	  Home: HomeScreen,
	  Settings: SettingsScreen,
	});
  1. 如何添加Drawer抽屉导航?
import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  TouchableWithoutFeedback,
  Button,
  Image,
  SafeAreaView
} from 'react-native';

import {
  createStackNavigator,
  createBottomTabNavigator,
  createDrawerNavigator,
  TabNavigator,
  TabBarBottom
} from 'react-navigation';
import HomeScreen from '../views/Home'

class MyHomeScreen extends React.Component {
  static navigationOptions = {
    drawerLabel: 'Home',
    drawerIcon: ({ tintColor }) => (
      <Image
        source={require('../assets/all.png')}
        style={[styles.icon, { tintColor: tintColor }]}
      />
    ),
  };

  render() {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button
          onPress={() => this.props.navigation.navigate('Notifications')}
          title="Go to notifications"
        />
      </SafeAreaView>
    );
  }
}

class MyNotificationsScreen extends React.Component {
  static navigationOptions = {
    drawerLabel: 'Notifications',
    drawerIcon: ({ tintColor }) => (
      <Image
        source={require('../assets/refresh_nav.png')}
        style={[styles.icon, { tintColor: tintColor }]}
      />
    ),
  };

  render() {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button
          onPress={() => this.props.navigation.goBack()}
          title="Go back home"
        />
      </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  icon: {
    width: 24,
    height: 24,
  },
});

export default MyDrawTable = createDrawerNavigator({
  Home: {
    screen: HomeScreen,
  },
  Notifications: {
    screen: MyNotificationsScreen,
  },
},
  {
    initialRouteName: 'Home',
  }
);

这里遗留了一个问题,如何把可以展开抽屉的页面不显示在抽屉导航上?也就是说我想要实现第一个进来的页面是Tab导航对应的第一个页面,这个页面也是可以滑动展开抽屉的页面,这个效果如何实现还暂未清楚,后期实现后会放到github上。

  1. 如何处理iphoneX兼容问题?
import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  Button,
  Image,
  SafeAreaView
} from 'react-native';

class MyHomeScreen extends React.Component {
  render() {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button
          onPress={() => this.props.navigation.goBack()}
          title="Go Back"
        />
      </SafeAreaView>
    );
  }
}

SafeAreaView将检测应用程序是否在iPhoneX上运行,这个属性只对ios设备起作用,默认情况下他会去适配iphone设备确保视图不会遮挡手机硬件。

使用forceInset可以对填充区域进行更多的控制。

forceInset使用键top | bottom | left | right | vertical | horizontal和值’always’ | ‘never’。或者您可以通过传递一个整数来完全覆盖填充。

  1. 如何配置不同tab页面的状态栏显示主题?

    不同的tab页面背景色可能不太一致,我们需要根据不同的主题色去设置不同的状态栏主题。

    当我们使用tab的时候,如果去设置StatusBar将会使用设置的最后一个配置,而不是根据视图去变化。

    要解决这个问题,我们必须做两件事:

    1.仅StatusBar在我们的初始tab屏幕上使用该组件。这允许我们确保使用正确的StatusBar配置。
    2.利用React Navigation中的事件系统和StatusBar隐式API,StatusBar在选项卡变为活动状态时更改配置。

  //在每个不同的tab页面监听
  componentDidMount() {
    this._navListener = this.props.navigation.addListener('didFocus', () => {
      StatusBar.setBarStyle('light-content');
      isAndroid && StatusBar.setBackgroundColor('#6a51ae');
    });
  }

  componentWillUnmount() {
    this._navListener.remove();
  }
  1. 如何从任何组件访问navigation导航?

比如说我们自己定义了一个小组件,然后在小组件里面调用了this.props.navigation.goBack()这时候会直接报错,因为找不到navigation对象,这时候我们就需要在用到小组件的地方去传入这个navigation对象,现在我们可以使用一个withNavigation方法。

import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';

class MyBackButton extends React.Component {
  render() {
    return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
  }
}

//这样就可以直接调用navigation的方法了
export default withNavigation(MyBackButton);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值