react native导航器
1. delete node_modules and package-lock.json
2. npm install
3. npm install --save react-navigation
4. npm install --save react-native-gesture-handler
5. react-native link
- demo1:创建一个 stack navigator
效果图如右图所示点击按钮go Details Screen后跳转新页面
项目文件夹如右图所示:
1.新建一个文件夹src,在src内新建config和screens文件夹,config内新建route.js文件用来放置配置代码,screens内放置页面代码
App.js
import React, { Component } from 'react';
import Route from './src/config/route'
class App extends Component {
render() {
return (
<Route />
);
}
}
export default App
route.js
import { createStackNavigator,createAppContainer } from "react-navigation";
// 引入页面组件
import Home from '../screens/Home'
import Details from '../screens/Details'
// 配置路由
const AppNavigator = createStackNavigator({
Home: Home,
Details: Details
});
const Route = createAppContainer(AppNavigator);
export default Route;
Home.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
const styles = {
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
}
class Home extends Component {
static navigationOptions = {
// 设置 title
title: "首页"
};
render() {
return (
<View style={styles.container}>
<Text>Home Screen</Text>
<Button
title="go Details Screen"
// 路由跳转
onPress={() => this.props.navigation.push("Details")}
/>
</View>
);
}
}
export default Home
Details.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
const styles = {
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
}
class Details extends Component {
render() {
return (
<View style={styles.container}>
<Text>Details Screen</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
export default Details
由上面的代码可知:
如果你处在堆栈深处,上面有多个页面,此时你想要将上面所有的页面都销毁,并返回第一个页面。 在这种情况下,要回到` Home `,可以使用` navigate('Home') `(而不是` push `! 尝试一下,看看有什么不同)。 另一个选择是` navigation.popToTop() `,它可以返回到堆栈中的第一个页面。
每次调用 ` push ` 时, 我们会向导航堆栈中添加新路由。 当你调用 ` navigate ` 时, 它首先尝试查找具有该名称的现有路由, 并且只有在堆栈上没有一个新路由时才会推送该路由。
this.props.navigation.goBack()实现返回
- 将上述代码在android上运行时,遇到如下问题Could not connect to development server
解决方法,利用Android Studio打开当前项目的MainActivity.java文件,进行如下修改
在合适位置加上下面两段代码:
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
完整代码示例
package com.awesomeproject;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "AwesomeProject";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
上述问题成功解决
- demo2传递参数给路由
1.在路由中传递
=> this.props.navigation.navigate("Details",{
itemId: 86,
otherParam: 'anything you want here'
2.接受路由的两种方法
const itemId = this.props.navigation.getParam('itemId', 'NO-ID');
const otherParam = this.props.navigation.state.params.otherParam;
3.
3.1设置标题栏显示的标题
页面组件navigationOptions,title这个属性用于设置标题栏的标题
3.2在标题中使用参数
在navigationOptions中使用this.props会报错,应该用{navigation> navigationOptions,screenProps}的对象调用它,再通过<code> navigation.state.params从navigation中获取参数
3.3使用setParams更新navigationOptions
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({title:'使用setParams更新navigationOptions'})}
/>
3.4调整标题样式
定制标题样式时有三个关键属性:headerStyle、headerTintColor和headerTitleStyle。
headerStyle:一个应用于 header 的最外层 View 的 样式对象, 如果你设置 backgroundColor ,他就是header 的颜色。
headerTintColor:返回按钮和标题都使用这个属性作为它们的颜色。
headerTitleStyle:如果我们想为标题定制fontFamily,fontWeight和其他Text样式属性,我们可以用它来完成。
如下所示,在某个页面可以实现对title的样式设定
static navigationOptions = {
// 设置 title
title: "首页",
headerStyle: {
backgroundColor:'#010101',
},
headerTintColor:'#fff',
headerTintStyle:{
fontWeight:'bold'
}
};
3.5跨页面共享通用的navigationOptions
设置每一个页面的title,只需要在配置文件route.js中设置
const AppNavigator = createStackNavigator({
Home: Home,
Details: Details
},
{
initialRouteName: 'Home',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#010101',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
}
);
4.完整代码(App.js如上所示,就不粘贴)
route.js
import { createStackNavigator,createAppContainer } from "react-navigation";
// 引入页面组件
import Home from '../screens/Home'
import Details from '../screens/Details'
// 配置路由
const AppNavigator = createStackNavigator({
Home: Home,
Details: Details
},
{
initialRouteName: 'Home',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#010101',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
// navigationOptions: {
// tabBarLabel: 'Home!',
// },
}
);
const Route = createAppContainer(AppNavigator);
export default Route;
Home.js
import React, { Component } from 'react';
import { View, Text, Button, Image } from 'react-native';
class LogoTitle extends Component {
render() {
return (
<View style={{flexDirection: 'row',justifyContent: 'flex-start',alignItems: 'flex-start'}}>
<Image source={require('../img/preview.jpg')}
style={{ width: 30, height: 30 }} />
</View>
);
}
}
class Home extends Component {
static navigationOptions = {
// 设置 title
// title: "首页",
headerTitle: "首页",
headerLeft: <LogoTitle />,
headerRight: (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
// 设置 title 样式
// headerStyle: {
// backgroundColor:'#010101',
// },
// headerTintColor:'#fff',
// headerTintStyle:{
// fontWeight:'bold'
// }
};
render() {
return (
<View>
<Text>Home Screen</Text>
<Button
title="go Details Screen"
// 路由跳转
onPress={() => this.props.navigation.navigate("Details",{
itemId: 86,
title: 'Detail Page',
otherParam: 'other'
})}
/>
</View>
);
}
}
export default Home
Details.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
class Details extends Component {
static navigationOptions = ({ navigation }) => {
return {
// 在标题中使用参数
// title: navigation.getParam('title', 'Details Screen title'),
title: navigation.state.params.title,
headerRight: (
<Button
onPress={() =>navigation.goBack()}
title="return home"
color="#fff"
/>
),
}
};
render() {
const itemId = this.props.navigation.getParam('itemId', 'NO-ID');
const otherParam = this.props.navigation.state.params.otherParam;
return (
<View>
<Text>Details Screen</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({title:'使用setParams更新navigationOptions'})}
/>
<Text>查看传参-----itemId:{itemId},otherParam:{otherParam}</Text>
</View>
);
}
}
export default Details
- demo3
- demo4
- demo5