React Native - 实现一个简单的分页导航菜单(tab标签切换)
作者:hangge | 2017-09-06 08:10
分页菜单(分段菜单)在许多 App 上都会用到。大多数新闻 App,如网易新闻、今日头条等,顶部都有个导航菜单。这个导航菜单是一组标签的集合,每个标签表示一个新闻类别,我们点击这个标签后下面就会切换到对应的分页面。
下面我们使用 React Native 来实现一个简单的分页菜单功能。
1,效果图
(1)界面顶部的菜单栏中有 4 个标签,点击标签即可切换到对应的页面。
(2)当前选中的菜单标签背景为灰色,其他标签背景为白色。

2,样例代码
(1)菜单栏组件(NaviBar.js)
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight,
Dimensions
} from 'react-native';
//获取设备的宽度和高度
var {
height: deviceHeight,
width: deviceWidth
} = Dimensions.get('window');
export default class NaviBar extends Component {
componentWillMount() {
//通过属性得知哪个导航按钮是当前的导航也,这个导航按钮将用灰色背景
this.buttonColors = this.props.naviBarStatus.map(
function(aNumber) {
if (aNumber == 0) return 'white';
return 'gray';
}
);
}
//四个按钮被按下时处理函数
_naviTab0Pressed() {
this.props.onNaviBarPress(0);
}
_naviTab1Pressed() {
this.props.onNaviBarPress(1);
}
_naviTab2Pressed() {
this.props.onNaviBarPress(2);
}
_naviTab3Pressed() {
this.props.onNaviBarPress(3);
}
render() {
return (
//根View
<View style={styles.naviRow}>
<TouchableHighlight onPress={this._naviTab0Pressed.bind(this)}>
<View style={[styles.button,{backgroundColor:this.buttonColors[0]}]}>
<Text style={styles.textStyle1}>
栏目一
</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={this._naviTab1Pressed.bind(this)}>
<View style={[styles.button,{backgroundColor:this.buttonColors[1]}]}>
<Text style={styles.textStyle1}>
栏目二
</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={this._naviTab2Pressed.bind(this)}>
<View style={[styles.button,{backgroundColor:this.buttonColors[2]}]}>
<Text style={styles.textStyle1}>
栏目三
</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={this._naviTab3Pressed.bind(this)}>
<View style={[styles.button,{backgroundColor:this.buttonColors[3]}]}>
<Text style={styles.textStyle1}>
栏目四
</Text>
</View>
</TouchableHighlight>
</View>
);
}
}
//样式
const styles = StyleSheet.create({
naviRow: {
flexDirection: 'row'
},
button: {
width: deviceWidth / 4, //导航栏每个标签宽度为屏幕1/4
height: 45,
justifyContent: 'center'
},
textStyle1: {
fontSize: 20,
textAlign: 'center'
}
});
(2)页面1(Page1.jpg)
每个分页面的顶部其实都放置了一个菜单栏组件,只不过菜单栏状态和菜单点击事件的处理逻辑有差异。
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View,
Text
} from 'react-native';
import NaviBar from './NaviBar';
export default class Page1 extends Component {
// 构造
constructor(props) {
super(props);
// 初始状态
this.onNaviBarPress = this.onNaviBarPress.bind(this);
// 不同的Page,需要修改下面的这个数组, 通过数组控制导航栏条目显示状态
this.naviStatus = [1, 0, 0, 0];
}
onNaviBarPress(aNumber) {
//不同的page需要修改下面这个switch的处理逻辑
switch (aNumber) {
case 0:
return;
case 1:
//通过replace切换
this.props.navigator.replace({
name: 'Page2'
});
return;
case 2:
this.props.navigator.replace({
name: 'Page3'
});
return;
case 3:
this.props.navigator.replace({
name: 'Page4'
});
return;
}
}
render() {
return (
<View style={styles.container}>
<NaviBar naviBarStatus={this.naviStatus}
onNaviBarPress={this.onNaviBarPress}/>
<View style={styles.whatLeft}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
whatLeft: { // 组件定义了一个上边框
flex: 1,
borderTopWidth: 1,
borderColor: 'black',
backgroundColor:'orange' //每个界面背景颜色不一样
}
});
(3)页面2(Page2.jpg)
下面高亮处显示的是 Page2 与 Page1 的差别,菜单栏状态和菜单点击事件的处理逻辑有差异,后面的 Page3、Page4 也差不多,这里就不再列出相关代码了。
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View,
Text
} from 'react-native';
import NaviBar from './NaviBar';
export default class Page1 extends Component {
// 构造
constructor(props) {
super(props);
// 初始状态
this.onNaviBarPress = this.onNaviBarPress.bind(this);
// 不同的Page,需要修改下面的这个数组, 通过数组控制导航栏条目显示状态
this.naviStatus = [0, 1, 0, 0];
}
onNaviBarPress(aNumber) {
//不同的page需要修改下面这个switch的处理逻辑
switch (aNumber) {
case 0:
this.props.navigator.replace({
name: 'Page1'
});
return;
case 1:
return;
case 2:
this.props.navigator.replace({
name: 'Page3'
});
return;
case 3:
this.props.navigator.replace({
name: 'Page4'
});
return;
}
}
render() {
return (
<View style={styles.container}>
<NaviBar naviBarStatus={this.naviStatus}
onNaviBarPress={this.onNaviBarPress}/>
<View style={styles.whatLeft}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
whatLeft: { // 组件定义了一个上边框
flex: 1,
borderTopWidth: 1,
borderColor: 'black',
backgroundColor:'green' //每个界面背景颜色不一样
}
});
(4)主页视图(index.android.js)
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
} from 'react-native';
import { Navigator } from 'react-native-deprecated-custom-components';
import Page1 from './Page1';
import Page2 from './Page2';
import Page3 from './Page3';
import Page4 from './Page4';
//默认应用的容器组件
class App extends Component {
//告知Navigator 模块切换时的效果
configureScene() {
return Navigator.SceneConfigs.FadeAndroid;
}
//根据传递的信息, 处理界面的切换
renderScene(router, navigator) {
switch (router.name) {
case 'Page1':
return <Page1 navigator={navigator}/>;
case 'Page2':
return <Page2 navigator={navigator}/>;
case 'Page3':
return <Page3 navigator={navigator}/>;
case 'Page4':
return <Page4 navigator={navigator}/>;
}
}
render() {
return (
//根View
<Navigator
initialRoute={{name:'Page1'}}
configureScene={this.configureScene}
renderScene={this.renderScene}/>
);
}
}
AppRegistry.registerComponent('HelloWorld', () => App);
全部评论(0)