美文网首页
RN自定义类似头条的滑动选择栏ScrollSelectView

RN自定义类似头条的滑动选择栏ScrollSelectView

作者: 6灰太狼9 | 来源:发表于2020-01-16 16:17 被阅读0次

    先上效果


    gif5新文件.gif

    代码

    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>
    

    相关文章

      网友评论

          本文标题:RN自定义类似头条的滑动选择栏ScrollSelectView

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