写在前面
这篇文章是“跟我一起学react-native”系列文章的第二篇。这系列文章会随着这个新闻项目的进行更新。想要跟我一起学习React Native的朋友可以关注我的微信公众号iOS进阶指南,或者订阅我的个人博客。
上一篇文章讲了React Native的环境搭建过程,本篇文章将讨论“水滴新闻”项目结构的搭建。
最终效果
项目文件结构
rn_shuidi
| - - - - - - - App.js
| - - - - - - - app.json
| - - - - - - - index.js
| - - - - - - - node_modules
| - - - - - - - shuidi
| - - - - - - - home
| - - - - - - - HomeScreen.js
| - - - - - - - NodeScreen.js
| - - - - - - - attention
| - - - - - - - me
| - - - - - - - android
| - - - - - - - ios
| - - - - - - - img
| - - - - - - - home_normal.png
| - - - - - - - home_selected.png
| - - - - - - - package.json
react-navigation
因为项目中包含多个页面,页面之间切换要使用TabBar和Navigation,因此要使用react-navigation这个框架。
安装react-navigation
cd rn_shuidi
npm install react-navigation
Navigation
下面以“主页为例”创建navigation
App.js
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation'
import HomeScreen from './shuidi/home/HomeScreen'
import NodeScreen from './shuidi/home/NodeScreen'
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen },
Nodes: { screen: NodeScreen }
})
StackNavigation可类比为iOS中的UINavigation,是一种栈类型的导航结构。
Home和Nodes分别是导航中的两个页面(控制器)。这里的名字会在执行导航行为的时候使用到。
screen参数是要放在导航中的页面。
HomeScreen.js
constructor(props) {
super(props)
this.state = { text: 'old' }
}
static navigationOptions = {
title: '主页',
};
<Text>{this.state.text}</Text>
<Button
title="Go to NodeScreen"
onPress={() => {
this.props.navigation.navigate('Nodes', {
title: '测试节点', callback: ((data) => {
this.setState({ text: data })
})
})
}}
/>
navigationOptions是对导航的配置,这里设置了title。相当于self.title="主页"
点击“Go to NodeScreen”这个Button
后会跳转到标签为“Nodes”的页面,如果App.js的HomeStack
中不包含“Nodes”标签则不会跳转。
title和callback分别是传递到“Nodes”页面的参数。其中callback是一个回调,用来进行反向传值。当“Nodes”页面以“data”为参数回调callback之后,this.setState
保存接受到的参数,当前页面就会随之改变。
NodeScreen.js
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('title', '节点'),
};
};
const callback = navigation.getParam('callback')
<Button
title="反向传值测试"
onPress={() => {
this.props.navigation.goBack(),
callback('我是反向传值')
}}
/>
navigation.getParam('title', '节点')
获取navigation
中的title
参数。
点击“反向传值测试”,回到上一级页面,之后调用callback,把字符串“我是反向传值”传递到上一级页面。
TabBar
App.js
createBottomTabNavigator(
{
Home: HomeStack,
Attention: AttentionStack,
Me: MeStack
},
{
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({focused, tintColor}) => {
const { routeName } = navigation.state
var title = ''
if (routeName === 'Home') {
title = '主页'
} else if (routeName === 'Attention') {
title = '关注'
} else {
title = '我'
}
return <Text>{title}</Text>
},
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
var iconName = '';
if (routeName === 'Home') {
iconName = focused ? require('./img/home_selected.png') : require('./img/home_normal.png')
} else if (routeName === 'Attention') {
iconName = focused ? require('./img/attention_selected.png') : require('./img/attention_normal.png')
} else {
iconName = focused ? require('./img/me_selected.png') : require('./img/me_normal.png')
}
return <Image
source={iconName}
style={{ width: 26, height: 26 }}
/>
}
}),
tabBarOptions: {
activeTintColor: 'blue',
inactiveTintColor: 'black',
}
}
)
tabBarLabel
和tabBarIcon
分别是当前标签页显示的标题和图片,其中图片根据focused
展示不同内容。
在navigationbar的子页面中隐藏tabbar
HomeStack.navigationOptions = ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
};
};
至此,项目结构搭建完成了。这个过程中如遇到问题可以参考遇到的问题和解决方案🎉🎉🎉
如果这篇文章能为你提供些许的帮助,我将不胜荣幸。如果你能慷慨的点个赞或者关注我,我将万分感激。