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)