ReactNative之自定义导航条
2017-05-16 本文已影响660人
袁峥
前言
眼看很多公司都开始尝试使用ReactNative,达到跨平台开发,最近也写了很多文章,希望让更多想了解的同学快速上手ReactNative.
如果喜欢我的文章,可以关注我微博:袁峥Seemygo
ReactNative之自定义导航条
- 用RN开发App,肯定需要用到导航条,系统自带的导航条不好用,一般都需要自定义导航条。
- 自定义导航条思想:模仿iOS导航控制器封装了一套RN的导航条
- 自定义导航条暴露属性
- 导航条展示什么控件,全部由外界传进来,这样设计,拓展性比较好
static propTypes = {
// 左边按钮
leftBarButtonItem:PropTypes.object,
// 中间View
middleView:PropTypes.object,
// 右边按钮
rightBarButtonItem:PropTypes.object,
// 中间标题
title:PropTypes.string,
// 中间标题样式
titleStyle:PropTypes.object,
// 导航条整个内容,完全由自己自定义
contentView:PropTypes.object
};
自定义导航条封装代码
/**
* Created by ithinkeryz on 2017/5/15.
*/
import React, { Component,PropTypes } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Dimensions
} from 'react-native';
import Common from './Common'
const NavigatorBarHeight = 64;
export default class CommonNavigationBar extends Component {
// 暴露属性
static propTypes = {
// 左边按钮
leftBarButtonItem:PropTypes.object,
// 中间View
middleView:PropTypes.object,
// 右边按钮
rightBarButtonItem:PropTypes.object,
// 中间标题
title:PropTypes.string,
// 中间标题样式
titleStyle:PropTypes.object,
// 导航条整个内容,完全由自己自定义
contentView:PropTypes.object
};
constructor(props){
super(props);
// 不能同时设置中间标题和中间View
if (this.props.title && this.props.middleView) throw "导航控制器不能同时设置title,middleView"
// 设置了contentView,不要同时设置其他属性
if (this.props.contentView && (this.props.middleView ||
this.props.rightBarButtonItem || this.props.title ||
this.props.titleStyle || this.props.contentView)
) throw "设置了contentView,其他设置无效,不要同时设置"
}
// 渲染内容层
renderContentView(){
return (
<View style={styles.contentViewStyle}>
{/*左边*/}
<View style={styles.leftStyle}>
{this.props.leftBarButtonItem}
</View>
{/*中间*/}
<View style={styles.middleStyle}>
{this.props.title?this.renderMiddleTitle():this.props.middleView}
</View>
{/*右边*/}
<View style={styles.rightStyle}>
{this.props.rightBarButtonItem}
</View>
</View>
)
}
// 渲染中间标题
renderMiddleTitle(){
return <Text style={[styles.middleTitleStyle,this.props.titleStyle]}>{this.props.title}</Text>
}
render() {
return (
<View style={[styles.barStyle,this.props.barStyle]}>
{this.props.contentView?this.props.contentView:this.renderContentView()}
</View>
);
}
}
var styles = StyleSheet.create({
barStyle:{
backgroundColor:'white',
width:Common.screenW,
height:NavigatorBarHeight,
flexDirection:'row'
},
contentViewStyle:{
flexDirection:'row',
width:Common.screenW,
height:44,
backgroundColor:'white',
position:'absolute',
bottom:0
},
leftStyle:{
flex:1,
justifyContent:'center',
alignItems:'center'
},
middleStyle:{
flex:4,
justifyContent:'center',
alignItems:'center'
},
rightStyle:{
flex:1,
justifyContent:'center',
alignItems:'center'
},
middleTitleStyle:{
fontSize:20,
color:'black',
fontWeight:'bold'
}
});
自定义导航条使用
- 这样封装,使用非常简单
- 封装思想:易用,可扩展,两个条件都达到了
export default class Reading extends Component {
render() {
return (
<View style={styles.viewStyle}>
<CommonNavigationBar middleView={this.renderMiddleView()}
leftBarButtonItem={this.renderLeftBarButtonItem()}
rightBarButtonItem={this.renderRightBarButtonItem()}
/>
</View>
);
}
renderMiddleView(){
return (
<View>
<Text>微信</Text>
</View>
)
}
renderLeftBarButtonItem(){
return (
<TouchableOpacity>
<Image source={{uri:'nav_item_game_click_icon'}} style={{width:20,height:20}}/>
</TouchableOpacity>
)
}
renderRightBarButtonItem(){
return (
<TouchableOpacity>
<Text>右边</Text>
</TouchableOpacity>
)
}
}
- 效果
![](https://img.haomeiwen.com/i304825/82ac9a1eb56332bd.png)