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;