美文网首页React-Native
react-native自定义导航栏(标题栏)

react-native自定义导航栏(标题栏)

作者: 07be9a549c1e | 来源:发表于2018-08-17 19:17 被阅读5次

    目前RN推荐react-navigation作为导航器,但是它的标题栏很多时候不能满足设计需求。需要自定义导航栏

    常见导航栏一般分为三部分,左边返回,中间标题,右边按钮。
    效果截图:


    35506728464988166.png 81045880374370172.jpg 326073020747697812.png 816127420187850721.jpg

    TitleBar.js

    "use strict";
    
    import React, {Component} from 'react';
    import PropTypes from 'prop-types';
    import {
       Text,
       View,
       Image,
       StatusBar,
       TouchableOpacity,
       StyleSheet,
    } from 'react-native'; 
    import Images from '../../image'
    import {width, unitWidth, titleHeight, statusBarHeight} from '../util/AdapterUtil'
    
    export default class TitleBar extends Component {
       static propTypes = {
           title: PropTypes.string.isRequired,
           navigation: PropTypes.object.isRequired,
           hideLeftArrow: PropTypes.bool,
           pressLeft: PropTypes.func,
           pressRight: PropTypes.func,
           left: PropTypes.string,
           backgroundColor: PropTypes.string,
           titleColor: PropTypes.string,
           right: PropTypes.oneOfType([
               PropTypes.string,
               PropTypes.object,
           ]),
           rightImage: Image.propTypes.source,
           LifeImage: Image.propTypes.source,
           statusBarBgColor: PropTypes.string,
           barStyle: PropTypes.string, 
       }
    
       static defaultProps = { 
           title: "",
           hideLeftArrow: false,
           pressRight: () => {
           },
       }
    
       back() {
           if (this.props.pressLeft) {
               this.props.pressLeft()
               return
           }
           this.props.navigation.goBack(); 
       }
    
       render() {
           const {backgroundColor, titleColor} = this.props
           return (
               <View style={[TitleStyle.titleBar, backgroundColor ? {backgroundColor: backgroundColor} : null]}> 
                       <StatusBar
                           backgroundColor={this.props.statusBarBgColor || "transparent"}
                           barStyle={this.props.barStyle || 'light-content'}
                           translucent={true}/> 
                    <View style={TitleStyle.statusBar}/>
    
                   <View style={TitleStyle.titleBarContent}>
                       {this.props.hideLeftArrow ? (
                           <View style={TitleStyle.left}/>
                       ) : (
                           <TouchableOpacity activeOpacity={1} onPress={this.back.bind(this)}
                                             style={TitleStyle.left}>
                               <Image style={TitleStyle.titleLeftImage}
                                      source={this.props.LifeImage || Images.public.arrow_left_white}/>
                               <Text style={TitleStyle.leftText}>{this.props.left}</Text>
                           </TouchableOpacity>
                       )}
                       <View style={TitleStyle.middle}>
                           <Text numberOfLines={1}
                                 style={[TitleStyle.middleTitle, titleColor ? {color: titleColor} : null]}>{this.props.title}</Text>
                       </View>
                       {this.renderRight()}
                   </View>
               </View>
           );
       }
    
       renderRight() {
           if (!this.props.right && !this.props.rightImage) {
               return <View style={TitleStyle.right}/>
           }
           return (
               <TouchableOpacity activeOpacity={1} style={TitleStyle.right}
                                 onPress={() => {
                                     this.props.pressRight()
                                 }}>
                   {typeof this.props.right == 'object' ? (this.props.right) : (
                       <Text style={TitleStyle.rightText}>{this.props.right}</Text>
                   )}
                   {this.props.rightImage ? (
                       <Image style={TitleStyle.rightImage} source={this.props.rightImage}/>
                   ) : (null)}
               </TouchableOpacity>
           )
       }
    }
    
    const TitleStyle = StyleSheet.create({
    
       titleBar: {
           width: width,
           height: titleHeight,
           backgroundColor: Color.themeColor,
       },
       titleBarContent: {
           flexDirection: 'row',   
           height: titleHeight,
           alignItems: 'center',   
           width: width,
           justifyContent: 'space-between',
           height: titleHeight - statusBarHeight,
       },
       titleBarSearchContent: {
           flexDirection: 'row',   
           height: titleHeight,
           alignItems: 'center',   
           width: width,
           height: titleHeight - statusBarHeight,
       },
    
       searchLeftIcon: {
           width: unitWidth * 30,
           height: unitWidth * 38,
           resizeMode: 'stretch',
           marginLeft: unitWidth * 24,
           marginRight: unitWidth * 15
       },
       searchLeftText: {
           width:unitWidth*140,
           fontSize: unitWidth * 30,
           color: "#ffffff",
       },
    
       searchBlock: {
           flexDirection: 'row',
           width: unitWidth * 500,
           height: unitWidth * 60,
           borderRadius: unitWidth * 30,
           backgroundColor: "white", 
           alignItems: 'center',
           paddingLeft: unitWidth * 30,
           paddingRight: unitWidth * 30
       },
    
       searchIcon: {
           width: unitWidth * 40,
           height: unitWidth * 40,
           resizeMode: 'stretch',
           marginRight: unitWidth * 30
       },
    
       searchBarInput: {
           width: unitWidth * 350,
           height: unitWidth * 60,
           fontSize: unitWidth * 30,
           backgroundColor: 'transparent',
           alignItems: 'center',
           margin: 0,
           padding: 0
       },
    
    
       left: {
           width: unitWidth * 180,
           height: titleHeight,
           flexDirection: 'row',
           justifyContent: 'flex-start',
           alignItems: 'center',
           paddingLeft: unitWidth * 10, 
       },
       middle: {
           width: width - unitWidth * 360,
           height: titleHeight,
           justifyContent: 'center',
           alignItems: 'center',
       },
       middleTitle: {
           fontSize: unitWidth * 40,
           color: "white",
           alignItems: 'center',
           justifyContent: 'center'
       },
    
       right: {
           width: unitWidth * 180,
           height: titleHeight,
           flexDirection: 'row',
           justifyContent: 'flex-end',
           alignItems: 'center',
           paddingRight: unitWidth * 30, 
       },
    
       leftText: {
           fontSize: unitWidth * 30,
           color: "white",
           alignItems: 'center',
           justifyContent: 'center'
       },
    
       rightText: {
           fontSize: unitWidth * 30,
           color: "white",
           alignItems: 'center',
           justifyContent: 'center'
       },
       rightImage: {
           width: unitWidth * 60,
           height: unitWidth * 60,
           resizeMode: 'contain',
           marginLeft: unitWidth * 5
       },
    
       titleLeftImage: {
           width: unitWidth * 50,
           height: unitWidth * 35,
           marginRight: unitWidth * 5,
           resizeMode: 'contain'
       },
    
       homeTitleIcon: {
           width: unitWidth * 213,
           height: unitWidth * 52,
           resizeMode: 'stretch'
       },
       titleRightImage: {
           width: unitWidth * 65,
           height: unitWidth * 65,
           resizeMode: 'contain'
       },
    statusBar:{
           width: width,
           height: statusBarHeight, 
           backgroundColor:'transparent'
    })
    

    TitleBar的基本使用

    render() {
            const {navigation} = this.props;
            return (
                <View style={BaseStyle.background}>
                    <TitleBar title={"意见反馈"} navigation={navigation}/>
                    <TextareaItem
                        placeholder={"请输入反馈内容,1000字以内"}
                        rows={8}
                        onChange={(message) => {
                            inputFeedback(message)
                        }}/>
                    <TextareaItem
                        placeholder={"联系方式"}
                        rows={1}
                        type={'number'}
                        value={MobilePhone}
                        onChange={(message) => {
                            inputMobile(message)
                        }}/>
                    <WhiteSpace size={60}/>
                    <LongButton 
                        text="提交"
                        onPress={()=>{
                        }}  />
                  </View>
              )
    }
    

    属性解析

    • title:中间的文字标题
    • navigation:react-natvigation导航器 用于返回上个页面
    • hideLeftArrow:是否隐藏左侧的返回按钮
    • pressLeft:左侧按钮的点击事件
    • pressRight:右侧按钮的点击事件
      -left:左侧按钮文字
    • backgroundColor:背景色
    • titleColor:标题的文字颜色
    • right:右侧按钮的文字或者组件
    • rightImage:右侧按钮的图标
    • LifeImage:左侧按钮的图片
    • barStyle:状态栏样式

    屏幕适配引用AdapterUtil.js

    相关文章

      网友评论

        本文标题:react-native自定义导航栏(标题栏)

        本文链接:https://www.haomeiwen.com/subject/gbmtiftx.html