美文网首页
React-native tabs组件开发以及问题记录

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

作者: 戴发夹的格格巫 | 来源:发表于2020-04-01 10:17 被阅读0次

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;

相关文章

网友评论

      本文标题:React-native tabs组件开发以及问题记录

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