先上效果图
可以通过属性修改选中颜色、默认颜色和默认选择项,以及控制底部标示的显示与否和动画时间。
代码
import React,{Component} from 'react';
import {View,Text,StyleSheet,Dimensions,TouchableHighlight,Animated,Easing} from 'react-native';
import PropsTypes from 'prop-types';
const {width,height} = Dimensions.get('window');
export default class SegmentView extends Component{
//定义属性的类型
static propTypes = {
titles: PropsTypes.array,
selectedIndex:PropsTypes.number,
defaultColor:PropsTypes.string,
selectColor:PropsTypes.string,
showSign:PropsTypes.bool,
callBack:PropsTypes.func,
animationDuring:PropsTypes.number,
}
//定义属性的默认值
static defaultProps = {
selectedIndex:0,
defaultColor:'#333',
selectColor:'#FE9540',
showSign:true,
animationDuring:100,
}
constructor(props){
super(props);
this.state = {
selectedIndex:props.selectedIndex,
signViewLeft:new Animated.Value(props.selectedIndex*width/props.titles.length),
}
}
_renderSignView(){
if (this.props.showSign) {
return <Animated.View style={[{left:this.state.signViewLeft,width:width/this.props.titles.length,backgroundColor:this.props.selectColor},styles.signView]}></Animated.View>
}
}
render() {
return(
<View style = {styles.container}>
{this.props.titles.map((item,i)=>{
return (
<TouchableHighlight
key = {i}
style={styles.itemView}
underlayColor='#fff'
onPress={this._onpressItem.bind(this,i)}
>
<Text style={{color:i==this.state.selectedIndex?this.props.selectColor:this.props.defaultColor,fontSize:16}}>{item}</Text>
</TouchableHighlight>
);
})}
{this._renderSignView()}
</View>
)
}
_onpressItem(i){
this.setSelectIndex(i);
if (this.props.callBack) {
this.props.callBack(i);
}
}
//外部调用这个方法可以修改选中项
setSelectIndex(index){
if (index==this.state.selectedIndex) {
return;
}
this.setState({
selectedIndex:index,
},()=>{
if (this.props.showSign) {
Animated.timing(
this.state.signViewLeft,
{
toValue:this.state.selectedIndex*width/this.props.titles.length,
duration: this.props.animationDuring,
easing: Easing.linear,
}
).start();
}
});
}
}
const styles = StyleSheet.create({
container:{
height:50,
width:'100%',
backgroundColor:'#fff',
flexDirection:'row',
alignItems:'center',
},
itemView:{
height:'100%',
flex: 1,
justifyContent:'center',
alignItems:'center',
},
signView:{
height:1,
position:'absolute',
bottom:0,
}
});
用法
<SegmentView
titles={['1','2','3']}
selectedIndex = {2}
showSign={true}
callBack={(i)=>{
console.warn(i);
}}
ref={r=>{this.segment=r}}
></SegmentView>