- 如何跳转到一个新的页面?
this.props.navigation.push(routerName)
- 如何返回之前的页面?
this.props.navigation.goBack()
- 如何在页面之间传递参数?
this.props.navigation.push('Discovery',{
id:1111,
name:'哈哈哈'
})
- 如何在新页面接收传递过来的参数?
//使用getParam()方法
const { navigation } = this.props;
const itemId = navigation.getParam('id', '参数没有的时候默认值'); //1111
const itemName = navigation.getParam('name', '没有的时候默认值'); //哈哈哈
//直接获取
this.props.navigation.state.params //存放了所有传递过来的路由参数
- 如何修改默认的灰色导航,自定义导航栏样式?
//静态在每个页面视图设置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 />
};
);
- 如何使用自定义按钮覆盖原始按钮?
//对应参数为:标题 左侧按钮 右侧按钮 (注意:自定义按钮需要自己添加事件)
static navigationOptions = {
headerTitle: <LogoTitle />,
headerLeft:<BackButton/>
headerRight: (
<Button
onPress={() => console.log('right button!')}
title="Info"
color="#fff"
/>
),
};
- 如何给自定义按钮加上处理事件?
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')
}
- 如何修改导航左侧的默认返回按钮?
//(规则:如果要在页面的返回按钮文本修改为自定义文本,需要去前置页面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',
},
}
};
-
如何展示那些全屏页面 即无需头部导航组件(例如登录页)?
要显示全屏页面需要去修改默认的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 />;
}
}
- 如何添加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,
});
- 如何添加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上。
- 如何处理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’。或者您可以通过传递一个整数来完全覆盖填充。
-
如何配置不同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();
}
- 如何从任何组件访问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);