先上效果
代码
import React,{Component} from 'react';
import {View,ScrollView,Text,StyleSheet,Dimensions,TouchableHighlight,UIManager,findNodeHandle,Animated,Easing} from 'react-native';
import PropsTypes from 'prop-types';
const {width,height} = Dimensions.get('window');
export default class ScrollSelectView extends Component{
static propTypes = {
titles:PropsTypes.array,
selectedIndex:PropsTypes.number,
selectedColor:PropsTypes.string,
defaultColor:PropsTypes.string,
callBack:PropsTypes.func,
scrollWidth:PropsTypes.number,
}
static defaultProps={
selectedIndex:0,
selectedColor:'red',
defaultColor:'#333',
scrollWidth:width,
}
constructor(props){
super(props);
this.state={
selectedIndex:props.selectedIndex,
contentWidth:0,
};
}
componentDidMount(){
//这里需要注意
setTimeout(() => {
this.setSelectIndex(this.state.selectedIndex,false);
}, 0);
}
render() {
return(
<ScrollView
style={[styles.container,{width:this.props.scrollWidth}]}
horizontal={true}
showsHorizontalScrollIndicator={false}
snapToInterval={100}
onContentSizeChange={(contentWidth,contentHeight)=>{
this.setState({contentWidth:contentWidth});
}}
ref={(r)=>{this.scrollView = r}}
>
{this.props.titles.map((item,i)=>{
var str = 'item'+i;
return (
<TouchableHighlight
style={styles.itemView}
key={i}
ref={str}
onPress={this._onpressItem.bind(this,i)}
underlayColor='#fff'
>
<Text style={{fontSize:i==this.state.selectedIndex?16:15,color:i==this.state.selectedIndex?this.props.selectedColor:this.props.defaultColor}}>{item}</Text>
</TouchableHighlight>
);
})}
</ScrollView>
);
}
_onpressItem(i){
this.setSelectIndex(i,true);
if (this.props.callBack) {
this.props.callBack(i);
}
}
setSelectIndex(i,animated){
var str = 'item'+i;
var handle = findNodeHandle(this.refs[str]);
UIManager.measure(handle ,(x, y, width, height, X, Y) => {
console.log('相对父视图位置x', x);
console.log('相对父视图位置y', y);
console.log('组件宽度', width);
console.log('组件高度', height);
console.log('绝对位置x', X);
console.log('绝对位置y', Y);
var originX = x+width/2-this.props.scrollWidth/2;
var maxoffsetX = this.state.contentWidth-this.props.scrollWidth;
if (originX<0) {
originX=0;
}
if(originX>maxoffsetX){
originX=maxoffsetX;
}
this.setState({
selectedIndex:i,
},()=>{
this.scrollView.scrollTo({x:originX,y:0,animated:animated});
});
})
}
}
const styles = StyleSheet.create({
container:{
height:40,
flexDirection:'row',
},
itemView:{
height:'100%',
padding:10,
justifyContent:'center',
alignItems:'center',
}
})
使用
<ScrollSelectView
titles={['关注','推荐','热点','北京','视频','图片','问答','娱乐','科技','懂车帝','财经','军事','体育','国际','健康','房产']}
selectedIndex={8}
callBack={(i)=>{
// console.warn(i);
}}
ref={r=>{this.scrollSelectView = r}}
></ScrollSelectView>