React Native学习教程之自定义NavigationBar详解

前言

在刚开始学习React Native的时候,版本还是0.20,问题一大堆,Navigation这个问题更是很多,首先,是NavigationBar的问题,NavigationIOS有NavigationBar,Navigation却需要自定义一个,最后,我想了想,还是自定义一个view,岂不更好,现在新公司不用RN,我正好有点时间,就把自定义的NavigationBar分享给大家。好了少废话,上代码;

示例代码

// NavigationBar 导航条的自定义封装
// create by 小广
'use strict';
import React, { Component,PropTypes } from 'react';
import {
 Image,
 Text,
 View,
 Platform,
 TouchableOpacity,
} from 'react-native'; 

import styles from './NavigationBarStyle' 

// 导航条和状态栏的高度
const STATUS_BAR_HEIGHT = 20
const NAV_BAR_HEIGHT = 44 

export default class NavigationBar extends Component {
 static defaultProps = {
 title: 'title',
 titleTextColor: '#383838',
 titleViewFunc () {},
 barBGColor: '#f8f8f8',
 barOpacity: 1,
 barStyle: 0,
 barBorderBottomColor: '#D4D4D4',
 barBorderBottomWidth: 0.8,
 statusbarShow: true,
 leftItemTitle: '',
 leftTextColor: '#383838',
 leftItemFunc () {},
 rightItemTitle: '',
 rightTextColor: '#383838',
 rightItemFunc () {},
 //leftImageSource: require('./nav_back.png'),
 };
 static propTypes = {
 title: PropTypes.string,   // nav标题
 titleTextColor: PropTypes.string, // nav标题颜色
 titleView: PropTypes.node,  // nav自定义标题View(节点)
 titleViewFunc: PropTypes.func, // nav的titleView点击事件
 barBGColor: PropTypes.string, // Bar的背景颜色
 barOpacity: PropTypes.number, // Bar的透明度
 barStyle: PropTypes.number, // Bar的扩展属性,nav样式(暂未使用)
 barBorderBottomColor: PropTypes.string, // Bar底部线的颜色
 barBorderBottomWidth: PropTypes.number, // Bar底部线的宽度
 statusbarShow: PropTypes.bool,  // 是否显示状态栏的20高度(默认true)
 leftItemTitle: PropTypes.string, // 左按钮title
 leftImageSource: PropTypes.node, // 左Item图片(source)
 leftTextColor: PropTypes.string, // 左按钮标题颜色
 leftItemFunc: PropTypes.func,  // 左Item事件
 rightItemTitle: PropTypes.string, // 右按钮title
 rightImageSource: PropTypes.node, // 右Item图片(source)
 rightTextColor: PropTypes.string, // 右按钮标题颜色
 rightItemFunc: PropTypes.func,  // 右Item事件
 }; 

 render() {
 // 判断左Item的类型
 var onlyLeftIcon = false; // 是否只是图片
 if (this.props.leftItemTitle && this.props.leftImageSource) {
  onlyLeftIcon = true;
 } else if (this.props.leftImageSource) {
  onlyLeftIcon = true;
 } 

 // 左侧图片title都没有的情况下
 var noneLeft = false;
 if (!(this.props.leftItemTitle.length > 0) && !(this.props.leftImageSource)) {
  noneLeft = true;
 } 

 // 判断是否自定义titleView
 var hasTitleView = false;
 if (this.props.title && this.props.titleView) {
  hasTitleView = true;
 } else if (this.props.titleView) {
  hasTitleView = true;
 } 

 // 判断右Item的类型
 var onlyRightIcon = false; // 是否只是图片
 if (this.props.rightItemTitle && this.props.rightImageSource) {
  onlyRightIcon = true;
 } else if (this.props.rightImageSource) {
  onlyRightIcon = true;
 } 

 // 右侧图片title都没有的情况下
 var noneRight = false;
 if (!(this.props.rightItemTitle.length > 0) && !(this.props.rightImageSource)) {
  noneRight = true;
 } 

 // 判断是否显示20状态栏高度
 let showStatusbar = this.props.statusbarShow;
 if (Platform.OS === 'android') {
  // 安卓不显示
  showStatusbar = false;
 }
 return (
  <View style={styles.nav_barView}>
  <View style={[styles.nav_bar,
   {
   backgroundColor: this.props.barBGColor,
   height: showStatusbar ? NAV_BAR_HEIGHT + STATUS_BAR_HEIGHT : NAV_BAR_HEIGHT,
   opacity: this.props.barOpacity
   },
   showStatusbar ? { paddingTop: STATUS_BAR_HEIGHT } : {}, this.props.barStyle]}>
   <View style={styles.nav_ItemView}>
   { // 左侧item
    !noneLeft
    ? <TouchableOpacity
     style={styles.nav_leftItem}
     onPress={this.props.leftItemFunc}>
     { // 左侧是图片还是文字
     onlyLeftIcon
     ? <Image style={styles.nav_leftImage}
        source={this.props.leftImageSource}/>
     : <Text style={[styles.nav_leftTitle,{color: this.props.leftTextColor}]}>
      {this.props.leftItemTitle}
      </Text>
     }
    </TouchableOpacity>
    : null
   }
   </View>
   {
   hasTitleView
   ? <TouchableOpacity style={styles.nav_titleView} onPress={this.props.titleViewFunc}>
    {this.props.titleView}
    </TouchableOpacity>
   : <View style={styles.nav_titleView}>
    <Text style={[styles.nav_title,{color:this.props.titleTextColor}]}>
     {this.props.title}
    </Text>
    </View>
   }
   <View style={styles.nav_ItemView}>
   { // 右侧item
    !noneRight
    ? <TouchableOpacity
     style={styles.nav_rightItem}
     onPress={this.props.rightItemFunc}>
     { // 右侧是图片还是文字
     onlyRightIcon
     ? <Image style={styles.nav_rightImage}
        source={this.props.rightImageSource}/>
     : <Text style={[styles.nav_rightTitle,{color: this.props.rightTextColor}]}>
      {this.props.rightItemTitle}
      </Text>
     }
    </TouchableOpacity>
    : null
   }
   </View>
  </View>
  <View style={{height:this.props.barBorderBottomWidth,backgroundColor:this.props.barBorderBottomColor}}></View>
  </View> 

 );
 }
} 

css样式:

// NavigationBarStyle 导航条的样式
// create by 小广
'use strict';
import {
 StyleSheet,
} from 'react-native'; 

export default StyleSheet.create({
 // navBar
 nav_barView:{
 justifyContent: 'center',
 },
 nav_bar: {
 //flex:1,
 flex: 1,
 flexDirection:'row',
 justifyContent: 'center',
 }, 

 // 标题纯title
 nav_title: {
 fontSize:17,
 }, 

 // titleView
 nav_titleView: {
 flex: 1,
 alignItems: 'center',
 justifyContent: 'center',
 }, 

 nav_ItemView:{
 width:80,
 justifyContent: 'center',
 }, 

 // 左Item
 nav_leftItem: {
 marginLeft:8,
 flex:1,
 justifyContent: 'center',
 alignSelf: 'flex-start',
 //backgroundColor:'#f00',
 }, 

 // 左Item为title
 nav_leftTitle: {
  marginRight:5,
  marginLeft:5,
  fontSize: 14,
 }, 

 // 左图片
 nav_leftImage: {
  margin:10,
  resizeMode:'contain',
 }, 

 // 右Item
 nav_rightItem: {
  marginRight:8,
  flex:1,
  justifyContent: 'center',
  alignSelf: 'flex-end',
  //backgroundColor:'#3393F2',
 }, 

 // 右Item为title
 nav_rightTitle: {
  marginRight:5,
  marginLeft:5,
  fontSize: 14,
 }, 

 // 右图片
 nav_rightImage:{
  margin:10,
  resizeMode:'contain',
  //backgroundColor:'#f00',
 },
 //resizeMode:'contain',
}); 

用法:引入之后

import NavigationBar from '你的存放路径/NavigationBar.js'

class XGRNDemo extends Component { 

 _leftItemAction() {
 console.log('左侧按钮点击了');
 } 

 _rightItemAction() {
 console.log('右侧按钮点击了');
 } 

 render() {
 return (
  <View style={styles.container}>
  <NavigationBar
   title='这个是标题'
   leftImageSource={require('./nav_back.png')}
   rightItemTitle='按钮'
   rightTextColor='#3393F2'
   leftItemFunc={this._leftItemAction.bind(this)}
   rightItemFunc={this._rightItemAction.bind(this)}/>
  <ScrollView style={styles.container}
   automaticallyAdjustContentInsets={false}
   keyboardShouldPersistTaps={true}
   keyboardDismissMode='on-drag'
   >
   <Text style={styles.welcome}>
   Welcome to React Native!
   </Text>
   <Text style={styles.instructions}>
   To get started, edit index.ios.js
   </Text>
   <Text style={styles.instructions}>
   Press Cmd+R to reload,{'\n'}
   Cmd+D or shake for dev menu
   </Text>
  </ScrollView>
  </View>
 );
 }
} 

const styles = StyleSheet.create({
 container: {
 flex: 1,
 backgroundColor: '#F5FCFF',
 },
 welcome: {
 fontSize: 20,
 textAlign: 'center',
 margin: 10,
 },
 instructions: {
 textAlign: 'center',
 color: '#333333',
 marginBottom: 5,
 },
}); 

其中可以自定义的属性

title: PropTypes.string,   // nav标题
titleTextColor: PropTypes.string, // nav标题颜色
titleView: PropTypes.node,  // nav自定义标题View(节点)
titleViewFunc: PropTypes.func, // nav的titleView点击事件
barBGColor: PropTypes.string, // Bar的背景颜色
barOpacity: PropTypes.number, // Bar的透明度
barStyle: PropTypes.number, // Bar的扩展属性,nav样式(暂未使用)
barBorderBottomColor: PropTypes.string, // Bar底部线的颜色
barBorderBottomWidth: PropTypes.number, // Bar底部线的宽度
statusbarShow: PropTypes.bool,  // 是否显示状态栏的20高度(默认true)
leftItemTitle: PropTypes.string, // 左按钮title
leftImageSource: PropTypes.node, // 左Item图片(source)
leftTextColor: PropTypes.string, // 左按钮标题颜色
leftItemFunc: PropTypes.func,  // 左Item事件
rightItemTitle: PropTypes.string, // 右按钮title
rightImageSource: PropTypes.node, // 右Item图片(source)
rightTextColor: PropTypes.string, // 右按钮标题颜色
rightItemFunc: PropTypes.func,  // 右Item事件 

效果如图:

ps:之前想上传到npm服务器,但是自己没搞成功,就这了吧..

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

时间: 2017-10-16

React Native中导航组件react-navigation跨tab路由处理详解

前言 大家应该都有所体会,我们在一般应用都有跨tab跳转的需求, 这就需要特别处理下路由,所以 下面是使用react-navigation作为路由组件的一种方式. 具体情境是: app分三大模块Home主页, Bill账单和Me我的, 对应三个tab. 现在需求是 Home push HomeTwo, HomeTwo push BillTwo, BillTwo 返回到 Bill账单首页. 方法如下: 首先选择路由结构, 选择使用最外层是StackNavigator, 然后包含3个TabNavig

react-native使用react-navigation进行页面跳转导航的示例

首先要确认已经配置好react-native的环境. # 创建一个native应用,SimpleApp,然后进入项目目录 react-native init SimpleApp cd SimpleApp # 通过npm安装最新版本的react-navigation npm install --save react-navigation # 运行程序 react-native run-android 引入Stack Navigator 对于我们的应用程序,我们想要使用堆栈式导航器,因为我们想要一个

Android Intent实现页面跳转的方法示例

应朋友们反馈的Android基础薄弱的问题,决定出一套Android基础教程,帮助大家复习,巩固Android基础,今天要讲的是Android中的Intent实现Android间的页面跳转. 增加Acrivity页面时,首先需要在MainActivity中对页面注册,比如 新建被跳转的页面OtherActivity,其对应的xml文件如下 activity_other <?xml version="1.0" encoding="utf-8"?> <

微信小程序常见页面跳转操作简单示例

本文实例讲述了微信小程序常见页面跳转操作.分享给大家供大家参考,具体如下: 1.保留当前页面,跳转到应用内另一个页面:wx.navigateTo({ url: '页面路径', }) 实例: pageSkip :function(){ wx.navigateTo({ url: '/page/admin/details', }) }, 2.关闭当前页面,返回到上一级或多级页面:wx.navigateBack({ url: '页面路径', }) 实例: pageSkip :function(){ wx

TP5框架页面跳转样式操作示例

本文实例讲述了TP5框架页面跳转样式操作.分享给大家供大家参考,具体如下: 1.效果图 2.上干货 为了增加对移动设备的支持,在  /application/common.php加入以下函数: function isMobile() { if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) { return true; } if (isset ($_SERVER['HTTP_VIA'])) { return stristr($_SERVER['HTTP_VIA'

详解react native页面间传递数据的几种方式

1. 利用react-native 事件DeviceEventEmitter 监听广播 应用场景: - 表单提交页面, A页面跳转到B页面选人, 然后返回A页面, 需要将B页面选择的数据传回A页面. - 多个多媒体来回切换播放,暂停后二次继续播放等问题. 代码如下: A页面 componentDidMount() { // 利用DeviceEventEmitter 监听 concactAdd事件 this.subscription = DeviceEventEmitter.addListener

react native中的聊天气泡及timer封装成的发送验证码倒计时

其实,今天我想把我近期遇到的坑都总结一下: 1.goBack的跨页面跳转,又两种方法,一可以像兔哥那样修改navigation源码,二可以用navigationActions 2.父子组件的传值,一可以用callBack  二可以用pubsub发布订阅模式 三可以用manager事件监听(a页面要显示的内容 有两种形式,一是从manager主动接收,也就是说不需要点击什么的获取数据,而是时时监听manager里数据的变化,第二种a页面获取要显示内容的形式是 点击出发,获取) 3 需要说的还是na

React Native react-navigation 导航使用详解

一.开源库介绍 今年1月份,新开源的react-natvigation库备受瞩目.在短短不到3个月的时间,github上星数已达4000+.Fb推荐使用库,并且在React Native当前最新版本0.44中将Navigator删除.react-navigation据称有原生般的性能体验效果.可能会成为未来React Native导航组件的主流军.本篇内容基于[ ^1.0.0-beta.9 ]版本来介绍关于该库的使用和实战技巧.可以看到,虽然是beta版本,不过基本稳定,大家可放心在项目中使用.

浅谈React Native 传参的几种方式(小结)

在React Native 中由于业务的需要, 我们往往要在诸多的页面间,组件之间做一些参数的传递与管理, 在这里我总结了几大经过验证,稳定好用的方式给大家 React Navigation 导航传值 推荐指数: ♥ ♥ ♥ ♥ ♥ 适用范围: 相互跳转的页面间传值 兼容性: IOS/Android 原理: React Navigation 为页面的 props 上挂载了 navigation 对象, 可用来做路由跳转,在做页面跳转时可以携带参数/回调方法前往目标页面, 从而达到传参的目的 说明

react native 仿微信聊天室实例代码

一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN技术做了个自定义模态弹窗rnPop组件. 一.项目简述 基于react+react-native+react-navigation+react-redux+react-native-swiper+rnPop等技术开发的仿微信原生App界面聊天室--RN_ChatRoom,实现了原生app启动页.As

React Native使用百度Echarts显示图表的示例代码

Echarts是百度推出的免费开源的图表组件,功能丰富,涵盖各行业图表.相信很多同学在网页端都使用过.今天我就来介绍下在React Native中如何使用Echarts来显示各种图表. 首先需要在我们的React Native项目中安装native-echarts组件,该组件是兼容IOS和安卓双平台的. 安装 npm install native-echarts --save 安装完成后在node_modules文件夹下会多出一个文件夹叫native-echarts. 目录结构如下图所示: 基础