React-native tabs组件开发以及问题记录

ReactNative中有个bug问题就是在Android6.0中scrollView中使用TextInput时设置textAlign=‘right’时,会导致滑动异常

当使用内部带有scrollView的tabs拆件时,当TextInput设置textAlign时,input输入时tabs会异常滑动到最后一个页面,例如react-native-scrollview-tabs > 0.7时,就会出现此问题,此第三方组件小于0.7的版本,ios使用scrollView,android使用ViewPagerAndroid,不会导致异常

因此自己写了一个可扩展的功能的tabs组件,根据需求后期可扩展功能

import React, { Component } from 'react';

import {

    StyleSheet,

    View,

    Text,

    ScrollView,

    FlatList,

    Dimensions,

    TouchableOpacity,

    ViewPagerAndroid,

    Platform

} from 'react-native';

import TabBar from './tabBar'

import uniqueId from 'lodash/uniqueId';

import PropTypes from 'prop-types';

import { px2dp } from '../_utils/';

const WIDTH = Dimensions.get('window').width;

let selfName = 'Tabs'

class Tabs extends Component {

    constructor(props){

        super(props);

        let { tabs = [], initialPage = 0, height } = this.props;

        this.state = {

            currentPage: initialPage,

            tabs: tabs,

            height:  px2dp(height * 1 ) || px2dp(50),

            tabClick: false

        }

        let { autoref } = props;

        this.id = autoref ? `AmapTabs_${autoref}` : uniqueId('AmapTabs_auto_ref');

        window.$instanceMap.set(this.id, this)


    }

      componentWillUnmount(){

        window.$instanceMap.delete(this.id)

      }

      componentDidMount(){

          let {initialPage = 0} = this.props

          this.setTabPage( initialPage * 1)

      }

      //跳转指定tab

      goToTab = (index) => {

        this.setTabPage(index)

      }

      tabClick(page) {

        this.onTabClick(page)

        this.setTabPage(page)

        this.setState({ tabClick:true})

      }

      changeTabState(index){

        this.setTabPage(index)

        const { onChange } = this.props;

        let callBackData = { index, componentName: selfName };

        onChange && onChange(callBackData)

      }

      onTabClick(val) {

        const { onTabClick } = this.props;

        let callBackData = { index: val, componentName: selfName };

        onTabClick && onTabClick(callBackData)

      }

      setTabPage(page) {

        let tabIndex = this.state.tabs.length - 1 

        if (page >= tabIndex) page = tabIndex

        this.setState({

            currentPage:page

        },()  => {

            if (Platform.OS === 'ios') {

                this._scrollView.scrollTo({x: page * WIDTH, y: 0, animated:false});

            } else {

                this._viewPager.setPageWithoutAnimation(page)

            }

        })  

      }

      componentWillUpdate (nextProps,nextState){

        if(nextState.currentPage !== this.state.currentPage && nextState.tabClick){

          this.changeTabState(nextState.currentPage)

          this.setState({ tabClick:false})

        }

    }

      renderContent = () => {

          if(Platform.OS === 'ios'){

            return(

                <ScrollView style={styles.scrollViewStyle}

                    ref={(scrollView) => this._scrollView = scrollView}

                    horizontal={true}

                    pagingEnabled={true}

             >

                {React.Children.map(this.props.children, (child, i) => {

                        return (<View style={{width:WIDTH,flex:1}}>{child}</View>);

                    })}

                </ScrollView>

            )

          } else {

              return (

                <ViewPagerAndroid

                    scrollEnabled={false}

                    ref = {(viewPager) => this._viewPager = viewPager}

                    style={styles.viewPager}

                    initialPage={0}>

                    {React.Children.map(this.props.children, (child, i) => {

                            return (<View key={i} style={{width:WIDTH,flex:1}}>{child}</View>);

                        })}

              </ViewPagerAndroid>

              )

          }




      }

        render(){

             const Height = this.state.height

             const {

                tabBarUnderlineStyle = {} ,

                tabBarTextStyle = {},

                tabBarInactiveTextColor = '#808080',

                tabBarActiveTextColor="#35CCA1",

                tabBarWidth = 2

             } = this.props

        return(

            <View style={styles.container}>

                <View style={{height:Height,width: this.WIDTH,display:'flex',flexDirection:'row'}}>

                 {this.props.tabs.map((tab, index) => {

                        if (index == this.state.currentPage) {

                            return (

                                <TouchableOpacity 

                                    style={{  

                                        flex: 1,

                                        display:'flex',

                                        justifyContent: 'center',

                                        alignItems: 'center'

                                    }}

                                    key={index} 

                                    onPress={() => this.tabClick(index)}>    

                                    <View style={styles.tabBarView}>

                                        <Text style={[{color:tabBarActiveTextColor,fontSize:px2dp(16)},tabBarTextStyle,{lineHeight:(Height - px2dp(tabBarWidth))}]}>{tab.title}</Text>

                                    </View>

                                    <View style={[{width:'100%',height:px2dp(tabBarWidth) ,backgroundColor:'rgb(53, 204, 161)'},tabBarUnderlineStyle]}></View>

                                </TouchableOpacity>

                            );

                        } else {

                            return (

                                <TouchableOpacity 

                                    style={{

                                        flex: 1,

                                        display:'flex',

                                        justifyContent: 'center',

                                        alignItems: 'center'

                                    }}

                                    key={index} 

                                    onPress={() => this.tabClick(index)}


                                >

                                    <View style={styles.tabBarView}>

                                        <Text style={[{color:tabBarInactiveTextColor,fontSize:px2dp(16)},tabBarTextStyle,{lineHeight:(Height - px2dp(tabBarWidth) )}]}>{tab.title}</Text>

                                    </View>

                                     <View style={{width:'100%',height: px2dp(tabBarWidth),backgroundColor:'#fff'}}></View>

                                </TouchableOpacity>


                            )

                        }

                    })   

                }

                </View>

                 {this.renderContent()}

        </View>

            );

    }

}

const styles = StyleSheet.create({

    container: {

        flex: 1,

        backgroundColor: '#fff',

    },

    tabBarView:{

        flex:1,

        backgroundColor: '#fff',

        justifyContent: 'center',

        alignItems: 'center'

    },

    scrollViewStyle: {

        backgroundColor: '#fff'

    },

    viewPager: {

        flex: 1

      },

      pageStyle: {

        alignItems: 'center',

        padding: 20,

      }


});

AmapTabs.propTypes = {

    /*tabs数据 | */

    tabs: PropTypes.array,

    /*tabs组件高度(不可用百分比) | */

    height: PropTypes.string,

     /*初始化index */

    initialPage: PropTypes.string,

     /*tabBar下划线样式 | */

    tabBarUnderlineStyle: PropTypes.string,

    /*tabBar激活Tab文字颜色 | */

    tabBarActiveTextColor: PropTypes.string,

    /*tabBar非激活Tab文字颜色 | */

    tabBarInactiveTextColor: PropTypes.string,

    /*tabBar文字样式 | */

    tabBarTextStyle: PropTypes.string,

    /*tabBar的宽度 | */

    tabBarWidth: PropTypes.number,

    /*tab变化时触发 $event: {componentName: 'Tabs', index: number} | */

    change: PropTypes.func,

    /*tab 被点击的回调 $event: {componentName: 'Tabs', index: number} | */

    tabClick: PropTypes.func,


};

export default Tabs;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容