React-Native之react-navigation(v2)

createStackNavigator

使用createStackNavigator来创建页面的跳转栈路径进行追踪

通过createStackNavigator来对路由进行配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const RootStack = createStackNavigator({
// 第一个对象用于对页面的路由表进行配置
Home: HomeScreen,
Details: DetailsScreen
}, {
// 通过第二个参数来对页面进行精细化配置
// 配置页面进入的路由
initialRouteName: 'Home'
})

export default class App extends React.Component {
render() {
return <RootStack />
}
}

路由页面跳转

页面的路由跳转可以通过多种方式, 其中一种最简单粗暴的方法就是通过onPress方法

1
2
3
4
5
6
onPress = {
() => {
// 跳转其实就是调用父组件中navigator对象中的navigate方法
return this.props.navigation.navigate('Details')
}
}

上面是一个跳转到Details页面的方式, 还有其他几种方法

1
2
3
4
// 往回跳转
this.props.navigation.goBack()
// 回到堆栈中的最顶层
this.props.navigation.popToTop()

另一点需要注意的是, 因为react navigation的机制问题, 当前页面中跳转当前页面, 是没有任何反应的

路由的页面传参

通过对navigate方法传递第二个参数的方式, 可以实现页面跳转的参数传递

1
2
3
4
this.props.navigation.navigate('Details', {
itemId: 86,
otherParam: 'anything you want here',
})

同样的, 接收参数也是需要使用类似的方式

1
2
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');

通过navigationgetParam方法进行参数的接收, 第一个参数为参数名称, 第二个参数为默认值

为页面增加页面参数

为页面增加参数可以直接使用navigationOptions, 对其进行赋值即可

1
2
3
static navigationOptions = {
title: 'Detail'
}

同样的, 我们也可以使用函数的方式对title进行赋值

1
2
3
4
5
static navigationOptions = ({navigation}) => {
return {
title: navigation.getParam('otherParam', 'a nested title')
}
}

由于这个特性, 我们就可以很方便地对页面的标题进行设置了, 比如说, 当我们点击某个按钮的时候

1
2
3
4
5
6
7
onPress={
() => {
return this.props.navigation.setParams({
otherParam: 'changed'
})
}
}

点击之后重新设置了navigation中的参数

为页面的标题增加自定义的样式

直接为navigationOptions额外传递参数即可

1
2
3
4
5
6
7
8
9
10
// 整个头部的样式
headerStyle: {
backgroundColor: '#f4511e',
},
// 头部的标题颜色
headerTintColor: '#fff',
// 头部标题的样式
headerTitleStyle: {
fontWeight: 'bold',
},

一般情况下, 我们的标题的样式在整个项目工程中是一样的, 所以此时我们可以直接在根路由中去为页面整体做样式的设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const RootStack = createStackNavigator({
Home: HomeScreen, // 通过createStackNavigator来进行页面的路由配置
Details: DetailsScreen
}, {
initialRouteName: 'Home', // 初始默认的路由
navigationOptions: {
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
});

自定义跳转的标题图标

对于页面的标题, 图标, 按钮等功能, 我们都可以对其进行定制, 下面是定制我们的标题的样式的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 我们定义一个组件, 用于显示在标题上
class LogoTitle extends React.Component {
render() {
return (<Image
source={require('./assets/delete.png')}
style={{
width: 30,
height: 30
}}/>);
}
}

...省略...
static navigationOptions = {
headerTitle: <LogoTitle />,
// 同样的, 对标题左侧和右侧, 也是一样可以进行设置的
headerRight: (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#000"
/>
),
headerLeft: (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#000"
/>
),
}

页面的标题向页面传参方式

页面标题向页面内的传参方式稍复杂, 需要定义一个中间参数, 通过每次对中间参数函数的方式去调用页面内的函数

需要注意的是, 此时标题的navigationOptions必须为函数, 否则无法实现此功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const navigaionOptions = ({navigaion}) => {
const params = navigation.state.params || {}
return {
headerTitle: <LogoTitle />,
headerRight: (
<Button
onPress={params.increaseCount}
title="add one"
color="#000"
/>
),
}
}

// state不需要放在constructor里面?
state = {
count = 0
}

// 在页面声明周期初始化的时候, 初始化设置increaseCount这个变量, 用于对页面进行初始化配置
componentWillMount() {
this.props.navigation.setParams({
increaseCount: this._increaseCount
})
}

_increaseCount = () => {
this.setState({
count: this.state.count + 1
})
}

全屏模态框

全屏模态框会暂时阻止原来页面的交互流程, 而直接开始模态框中的交互

我们对页面分为两个部分, 一个是页面分类, 另一个是模态框的分类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const MainStack = createStackNavigator({
Home: HomeScreen, // 通过createStackNavigator来进行页面的路由配置
Details: DetailsScreen
}, {
initialRouteName: 'Home', // 初始默认的路由
navigationOptions: {
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
});

const RootStack = createStackNavigator(
{
// 页面堆栈
Main: {
screen: MainStack,
},
// 模态框堆栈
MyModal: {
screen: ModalScreen,
},
},
{
mode: 'modal',
headerMode: 'none',
}
);

export default class App extends React.Component {
render() {
return <RootStack/>;
}
}

这样配置好之后, 需要使用modal全屏页面的时候, 直接调用跳转逻辑即可

1
2
3
4
5
6
7
// 在页面中
<Button
title = "Go to Modal"
onPress = {
() => this.props.navigation.navigate('MyModal')
}
/>

tab导航

tab导航的定义方式很简单, 通过从react-navigation中引入不同的配置函数即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import {createBottomTabNavigator} from 'react-navigation';

// 定义页面的tab堆栈
const TabStack = createBottomTabNavigator({
// 定义的键值对中, 键名默认为tab的名称, 可在页面中定义title来覆盖这个名称
Home111: HomeScreen,
Details: SettingsScreen
})

// 同样的, 将这个堆栈从app根组件中渲染即可
export default class App extends React.Component {
render() {
return <TabStack/>;
}
}

抽屉导航

文章目录
  1. 1. createStackNavigator
    1. 1.1. 通过createStackNavigator来对路由进行配置
    2. 1.2. 路由页面跳转
    3. 1.3. 路由的页面传参
    4. 1.4. 为页面增加页面参数
    5. 1.5. 为页面的标题增加自定义的样式
    6. 1.6. 自定义跳转的标题图标
    7. 1.7. 页面的标题向页面传参方式
    8. 1.8. 全屏模态框
  2. 2. tab导航
  3. 3. 抽屉导航
|