React Native 控件封装

本文介绍了为实现Android与iOS界面统一而封装的几个关键UI组件:SearchBar、Segment及带输入框的Modal,并提供了详细的代码实现。

由于Android 与IOS 界面的差异,对一些控件进行了封装:SearchBar,Segment,Modal,TextInput,实现Android 与IOS 界面 统一。

1、SearchBar的封装

import React, {Component} from 'react';
import {View, TouchableOpacity, Dimensions, TextInput} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'
import {px2dp} from 'js/utils/commonUtils';
const deviceWidth = Dimensions.get('window').width;
import colors from 'js/themes/colors';


/**
 *  SearchBar
 *  created by yang on 2017/10/16
 */
export default class SearchBar extends Component {
  constructor(props) {
    super(props);
    this.state = {}
  }

  static propTypes = {
    editable:React.PropTypes.bool,//输入框是否可编辑
    keyboardType:React.PropTypes.any,//输入框弹出键盘类型

    /********文字****************/
    placeholderText:React.PropTypes.any,//输入框占位字符


    /********字体****************/
    placeHolderTextFontColor: React.PropTypes.any,//输入框占位字体颜色
    textInputMaxSize: React.PropTypes.number,//输入框最大字数
    textInputFontSize:React.PropTypes.number,//输入框字体大小
    textInputFontColor:React.PropTypes.any,//输入框字体颜色


    /********样式****************/
    textInputViewHeight: React.PropTypes.number,//输入框背景高度
    textInputViewWidth: React.PropTypes.number,//输入框背景宽度
    textInputViewBackGroundColor: React.PropTypes.any,//输入框背景颜色

    /********回调****************/
    onChangeTextCallBack: React.PropTypes.func,//输入框字体变化的指令
    onChangeCallBack: React.PropTypes.func,//输入框onChange的指令
    onFocusCallBack: React.PropTypes.func,//输入框onFocus的指令
    onBlurCallBack: React.PropTypes.func,//输入框onBlur的指令
    onSearchPressedCallBack:React.PropTypes.func,//点击搜索图标时的指定

  };

  render() {
    return (
      <View style={styles.containers}>
        <View style = {{...styles.textInputViewStyle,
                          height: this.props.textInputViewHeight ? this.props.textInputViewHeight:32,
                          width:this.props.textInputViewWidth? this.props.textInputViewWidth:deviceWidth-55,
                          backgroundColor:this.props.textInputViewBackGroundColor? this.props.textInputViewBackGroundColor : colors.colorEC}}>
          <Icon name="ios-search"  size={px2dp(24)}  color={colors.arrowColor} />
          <TextInput underlineColorAndroid="transparent"
                     style={{...styles.textInputStyle,
                       fontSize: this.props.textInputFontSize?this.props.textInputFontSize:13,
                       color:this.props.textInputFontColor?this.props.textInputFontColor:colors.textTitle,}}
                     keyboardType={this.props.keyboardType?this.props.keyboardType:"default"}
                     placeholder= {this.props.placeholderText? this.props.placeholderText:"关键字"}
                     maxLength = {this.props.textInputMaxSize? this.props.textInputMaxSize:15}
                     placeholderTextColor={this.props.placeHolderTextFontColor? this.props.placeHolderTextFontColor :colors.placeHolderTextColor}
                     onChangeText={this.props.onChangeTextCallBack}
                     onChange={this.props.onChangeCallBack}
                     onFocus={this.props.onFocusCallBack}
                     onBlur={this.props.onBlurCallBack}
                     editable={this.props.editable===false?this.props.editable:true}>
          </TextInput>
        </View>
        <TouchableOpacity  onPress={this.props.onSearchPressedCallBack.bind(this)}>
          <View style = {{...styles.searchIconViewStyle,
                          height:this.props.textInputViewHeight ? this.props.textInputViewHeight:32}}>
            <Icon name="ios-search" size={px2dp(24)}  color={colors.appGreen}/>
          </View>
        </TouchableOpacity>
      </View>
    )
  }
  }

const styles =
  {
   containers:{
     flexDirection: 'row',
     display: 'flex',
     width:'100%',
     justifyContent:'space-between',
     backgroundColor:colors.white,
     paddingLeft:10,
     paddingRight:15,
     paddingTop:10,
     paddingBottom:10,

   },
    textInputViewStyle:{
      flexDirection: 'row',
      display: 'flex',
      alignItems:'center',
      borderRadius:10,
      paddingLeft:10,
      paddingRight:10,
      marginRight:2
    },
    textInputStyle:{
      flex: 1,
      paddingVertical: 0,
      marginLeft:3,
      paddingHorizontal: 10,
    },
    searchIconViewStyle:{
     flexDirection: 'row',
      display: 'flex',
      alignItems:'center',
    }


  };


2、segment 的封装:


import React, {Component} from 'react';
import {TouchableOpacity,SegmentedControlIOS,  Platform,Image} from 'react-native';
import { SegmentedControl } from 'antd-mobile';

/**
 * segment used on Android & ios
 * Created by yang on 2017/10/17.
 */

export default class SegmentedControlBoth extends Component {

  render(){
    return Platform.OS === 'ios'?(
      <SegmentedControlIOS {...this.props}>{this.props.children}</SegmentedControlIOS>
    ):(
      <SegmentedControl {...this.props}>{this.props.children}</SegmentedControl>
    )
  }
}


3、带输入框的Modal 封装

import React from 'react';
import {Text, View, Modal, Image, Dimensions, TouchableOpacity, TextInput} from 'react-native';

const {height, width} = Dimensions.get('window');
import colors from 'js/themes/colors';

/**
 *  custom TextInputModal.js
 *  contains Title, Des, TextInput, cancel ,confirm
 *  created by yang on 2017/09/27
 */
export default class TextInputModal extends React.Component {
  constructor(props) {
    super(props);
    this.state = {}
  }

  static propTypes = {
    ModalVisible: React.PropTypes.bool,//是否显示对话框
    TitleVisible: React.PropTypes.bool,//是否显示标题
    TextInputVisible: React.PropTypes.bool,//是否显示输入框
    DescriptionVisible: React.PropTypes.bool,//是否显示描述


    /********宽高、距离****************/
    HeightModal: React.PropTypes.any,//这个弹窗的高度
    WidthModal: React.PropTypes.any,//这个弹窗的宽度
    TitleHeight: React.PropTypes.any,//这个弹窗的标题高度
    TitleWidth: React.PropTypes.any,//这个弹窗的标题宽度
    DescriptionHeight: React.PropTypes.any,//这个弹窗的标题高度
    DescriptionWidth: React.PropTypes.any,//这个弹窗的标题宽度
    BottomHeight: React.PropTypes.any,//这个弹窗的底部高度
    BottomWidth: React.PropTypes.any,//这个弹窗的底部宽度
    TextInputHeight: React.PropTypes.any,//这个弹窗的输入框高度
    TextInputWidth: React.PropTypes.any,//这个弹窗的输入框宽度
    TextInputMarginBottom: React.PropTypes.any,//输入框与底部的距离
    TitleMarginTop: React.PropTypes.any,//标题顶部距离
    TitleMarginBottom: React.PropTypes.any,//标题底部距离
    DescriptionMarginBottom: React.PropTypes.any,//描述底部距离


    /********字体****************/
    TitleFontSize: React.PropTypes.number,//标题的文字大小
    TitleFontColor: React.PropTypes.any,//标题的文字颜色
    DescriptionFontSize: React.PropTypes.number,//描述的文字大小
    DescriptionFontColor: React.PropTypes.any,//描述的文字颜色
    BottomFontSize: React.PropTypes.number,//下面取消确定的文字大小
    BottomFontColor: React.PropTypes.any,//下面取消确定的文字的颜色
    TextInputFontSize: React.PropTypes.number,//输入框字体大小
    TextInputFontColor: React.PropTypes.any,//输入框字体颜色
    TextInputPlaceHolderTextFontColor: React.PropTypes.any,//输入框占位字体颜色
    TextInputMaxLength: React.PropTypes.number,//输入框字体长度限制


    /********文字****************/
    TitleText: React.PropTypes.any,//标题文字
    DescriptionText: React.PropTypes.any,//描述文字
    CancelText: React.PropTypes.any,//取消文字
    OkText: React.PropTypes.any,//确定文字
    TextInputPlaceHolderText: React.PropTypes.any,//输入框占位内容
    TextInputDefaultText: React.PropTypes.any,//输入框默认内容


    /********回调****************/
    onChangeTextCallBack: React.PropTypes.func,//输入框字体变化的指令
    confirmCallBack: React.PropTypes.func,//回调确定的指令
    cancelCallBack: React.PropTypes.func,//回调取消的指令


  }


  render() {
    return (
      <View>
        <Modal
          animationType={"fade"}
          transparent={true}
          visible={this.props.ModalVisible}
          onRequestClose={this.props.cancelCallBack.bind(this)}
        >
          <TouchableOpacity
            style={styles.ViewPage} onPress={() => {
          }}>

            <View style={styles.ViewPage}>
              <View style={{
                height: this.props.HeightModal ? this.props.HeightModal : 200,
                width: this.props.WidthModal ? this.props.WidthModal : 303,
                backgroundColor: 'white',
                borderRadius: 8
              }}>
                {this.props.TitleVisible && <View style={{     /****title******/
                  height: this.props.TitleHeight ? this.props.TitleHeight : 44,
                  width: this.props.TitleWidth ? this.props.TitleWidth : 303,
                  alignItems: 'center',
                  justifyContent: 'center'
                }}>
                  <Text style={{
                    fontSize: this.props.TitleFontSize ? this.props.TitleFontSize : 16,
                    color: this.props.TitleFontColor ? this.props.TitleFontColor : colors.textTitle,
                    marginTop: this.props.TitleMarginTop ? this.props.TitleMarginTop : 18,
                    marginBottom: this.props.TitleMarginBottom ? this.props.TitleMarginBottom : 10
                  }}>{this.props.TitleText}</Text>
                </View>}

                {this.props.DescriptionVisible && <View style={{   /**** Description ******/
                  height: this.props.DescriptionHeight, width: this.props.DescriptionWidth,
                  alignItems: 'center', justifyContent: 'center'
                }}>
                  <Text style={{
                    fontSize: this.props.DescriptionFontSize ? this.props.DescriptionFontSize : 14,
                    color: this.props.DescriptionFontColor ? this.props.DescriptionFontColor : colors.textTitle,
                    marginBottom: this.props.DescriptionMarginBottom ? this.props.DescriptionMarginBottom : 10
                  }}>{this.props.DescriptionText}</Text>
                </View>}



                {this.props.TextInputVisible && <TextInput style={{ /*****输入框******/
                    flex: 1,
                    padding: 10,
                    borderRadius: 10,
                    justifyContent: 'center',
                    alignItems:'center',
                    alignSelf:'center',
                    borderWidth: 1,
                    borderColor: colors.dividerLineColor,
                    height: this.props.TextInputHeight ? this.props.TextInputHeight : 80,
                    width: this.props.TextInputWidth ? this.props.TextInputWidth : 250,
                    marginBottom: this.props.TextInputMarginBottom ? this.props.TextInputMarginBottom : 10,
                    fontSize: this.props.TextInputFontSize ? this.props.TextInputFontSize : 13,
                    color: this.props.TextInputFontColor ? this.props.TextInputFontColor : colors.textTitle,
                  }}
                  underlineColorAndroid="transparent"
                  placeholder={this.props.TextInputPlaceHolderText}
                  placeholderTextColor={this.props.TextInputPlaceHolderTextFontColor ? this.props.TextInputPlaceHolderTextFontColor : colors.placeHolderTextColor}
                  multiline={true}
                  maxLength={this.props.TextInputMaxLength}
                  onChangeText={this.props.onChangeTextCallBack? this.props.onChangeTextCallBack.bind(this):''}>{this.props.TextInputDefaultText}</TextInput>}



                <View style={{  /***取消确定**/
                  height: this.props.BottomHeight ? this.props.BottomHeight : 47,
                  width: this.props.BottomWidth ? this.props.BottomWidth : 303,
                  flexDirection: 'row',
                  borderTopWidth: 1,
                  borderColor: colors.dividerLineColor
                }}>
                  <TouchableOpacity style={{flex: 1}} onPress={this.props.cancelCallBack.bind(this)}
                  >
                    <View style={{
                      flex: 1,
                      alignItems: 'center',
                      justifyContent: 'center',
                      borderRightWidth: 1,
                      borderColor: colors.dividerLineColor
                    }}>
                      <Text style={{
                        fontSize: this.props.BottomFontSize ? this.props.BottomFontSize : 14
                        , color: this.props.BottomFontColor ? this.props.BottomFontColor : colors.colorNine
                      }}>{this.props.CancelText ? this.props.CancelText : '取消'}</Text>
                    </View>
                  </TouchableOpacity>
                  <TouchableOpacity style={{flex: 1}}
                                    onPress={
                                      this.props.confirmCallBack.bind(this)
                                    }>
                    <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
                      <Text style={{
                        fontSize: this.props.BottomFontSize ? this.props.BottomFontSize : 14
                        , color: this.props.BottomFontColor ? this.props.BottomFontColor : colors.blue
                      }}>{this.props.OkText ? this.props.OkText : '确定'}</Text>
                    </View>
                  </TouchableOpacity>
                </View>


              </View>
            </View>
          </TouchableOpacity>
        </Modal>


      </View>);
  }
}


const styles =
  {
    ViewPage: {
      flex: 1,
      width: '100%',
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: 'rgba(0,0,0,0.2)'
    }
  };


转载请标明引用连接 http://blog.youkuaiyun.com/xiaoduo0987/article/details/78266557,谢谢



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值