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服务器,但是自己没搞成功,就这了吧..

总结

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

(0)

相关推荐

  • 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 对于我们的应用程序,我们想要使用堆栈式导航器,因为我们想要一个

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

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

  • ASP.NET CORE学习教程之自定义异常处理详解

    为什么异常处理选择中间件? 传统的ASP.NET可以采用异常过滤器的方式处理异常,在ASP.NET CORE中,是以多个中间件连接而成的管道形式处理请求的,不过常用的五大过滤器得以保留,同样可以采用异常过滤器处理异常,但是异常过滤器不能处理MVC中间件以外的异常,为了全局统一考虑,采用中间件处理异常更为合适 为什么选择自定义异常中间件? 先来看看ASP.NET CORE 内置的三个异常处理中间件 DeveloperExceptionPageMiddleware, ExceptionHandler

  • kotlin 官方学习教程之基础语法详解

    kotlin 官方学习教程之基础语法详解 Google 在今天的举行了 I/O 大会,大会主要主要展示内有容 Android O(Android 8.0)系统.Google Assistant 语音助手.Google 智能音箱.人工智能.机器学习.虚拟现实等.作为一个 Android 开发者,我关心的当然是 Android O(Android 8.0)系统了,那么关于 Android O 系统的一个重要消息是全面支持 Kotlin 编程语言,使得 Kotlin 成为了 Android 开发的官方

  • React Native 的动态列表方案探索详解

    目录 背景 技术方案介绍 内存 异常处理 未来规划 背景 时至2022,精细化运营已经成为了各大App厂商的强需求,阿里的 DinamicX.Tangram 大家应该都很熟悉了,很多App厂商也自研了一些类似框架,基于DSL的动态化方案虽然有性能上的一些优势,但是毕竟不是图灵完备,一些需要逻辑动态下发的需求实现成本偏高,或由于DSL本身限制无法实现,针对这个问题我们使用RN进行了一下探索尝试, 利用我们已经相对完善的RN基建,结合客户端列表能力低成本的实现了一套的动态化能力,同时兼顾一定的性能体

  • React特征学习之Form格式示例详解

    目录 Form 样式 React hook Form 样式 首先来看一个简单Form, 式样如下 import * as React from 'react'; const LoginForm = () => { return ( <form> <div> // Notice: 这里要用htmlFor,相当于id <label htmlFor="email">Email</label> <input id="emai

  • Flutter学习之实现自定义themes详解

    目录 简介 MaterialApp中的themes 自定义themes的使用 总结 简介 一般情况下我们在flutter中搭建的app基本上都是用的是MaterialApp这种设计模式,MaterialApp中为我们接下来使用的按钮,菜单等提供了统一的样式,那么这种样式能不能进行修改或者自定义呢? 答案是肯定的,一起来看看吧. MaterialApp中的themes MaterialApp也是一种StatefulWidget,在MaterialApp中跟theme相关的属性有这样几个: fina

  • React Native之prop-types进行属性确认详解

    属性确认的作用 使用 React Native 创建的组件是可以复用的,所以我们开发的组件可能会给项目组其他同事使用.但别人可能对这个组件不熟悉,常常会忘记使用某些属性,或者某些属性传递的数据类型有误. 因此我们可以在开发 React Native 自定义组件时,可以通过属性确认来声明这个组件需要哪些属性.这样,如果在调用这个自定义组件时没有提供相应的属性,则会在手机与调试工具中弹出警告信息,告知开发者该组件需要哪些属性. React Native已经升级到0.51.0了,版本升级很快,但是对老

  • React Native中Mobx的使用方法详解

    前言 从今天开始我们来搞搞状态管理可否,这几天没怎么写博客,因为被病魔战胜了,tmd,突然的降温让我不知所措,大家最近注意安全,毕竟年底了,查的严,呸,大家注意保暖 特别声明:写该文只是写一下用MobX的思路,有很多地方我会直接放官网链接,因为官网已经写的够详细了 首先来个比较简单的,MobX. 引用官网上的一句话: MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程(transparently applying functional reactive programming - TF

  • Kotlin学习教程之操作符重载详解

    前言 在 Kotlin 中,我们可以用 约定的操作符,代替 调用代码中以特定的命名定义的函数,来实现 与之对应的操作.例如在类中定义了一个名为 plus 的特殊方法,就可以使用加法运算符 + 代替 plus() 的方法调用.由于你无法修改已有的接口定义,因此一般可以通过 扩展函数 来为现有的类增添新的 约定方法,从而使得 操作符重载 这一语法糖适应任何现有的 Java 类. 算术运算符 我们就从最简单直接的例子 + 这一类算术运算符开始. data class Point(val x: Int,

  • Laravel学习教程之广播模块详解

    前言 本文主要给大家介绍了关于Laravel广播模块的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 注意:本文是基于Laravel 5.4版本的路由模块代码进行分析书写: 简介 广播是指发送方发送一条消息,订阅频道的各个接收方都能及时收到消息:比如 A同学写了一篇文章,这时候 B同学在文章底下评论了,A同学在页面上是不用刷新就能收到提示有文章被评论了,这个本质上就是A同学收到了广播消息,这个广播消息是由B同学评论这个动作触发了发送广播消息: 在整个广播行为中,有一个重

随机推荐