美文网首页
react-native 使用ScrollView实现滚动定位以

react-native 使用ScrollView实现滚动定位以

作者: 物联白菜 | 来源:发表于2021-03-05 12:58 被阅读0次

效果图:


3FFE2DC8D6711BCC0EBBF6C3810A431C.png C151D3A05EBD807331DED5D694EEF7F3.png

1、不用管里面遍历了什么数据,利用onLayout获取滚动内容里面元素的高度集合
滑动自动地位到导航栏

        this.state = {
            curIndex:0,
            scrollContentArr:[
                {name:'艺考服务'},
                {name:'院校定制'},
                {name:'设计素材'},
                {name:'兼职全职'},
                {name:'文艺周边'},
                {name:'艺术历史'},
                {name:'更多服务'},
                {name:'艺考服务'},
                ],
        };

//滚动内容
<ScrollView showsVerticalScrollIndicator={false}
                                    style={{marginTop: -1}}
                                    ref={scrollView => this.scrollView = scrollView}
                                    onScroll={Animated.event(
                                        [{ nativeEvent: {contentOffset: { y: 0 }}}],  //初始化滚动的距离
                                        { listener: (event) => {
                                                let scrollY = event.nativeEvent.contentOffset.y
                                                // console.log('获取滚动的距离',scrollY)
                                                for(let i = 0;i<arr.length-1;i++){
                                                    // console.log('i==',arr,i)
                                                    if(scrollY<arr[0].height-40){   //如果滚动距离第二个40前,index一直都是0
                                                        this.setState({
                                                            curIndex:0
                                                        })
                                                    }else if(scrollY>arr[i+1].y-(arr[i].height/2)){   //除了第一个,其他的滚动到当前盒子的一半时,给下一个盒子的index
                                                        this.setState({
                                                            curIndex:i+1
                                                        })
                                                    }
                                                }
                                                // for(let i=0;i<arr.length;i++){
                                                //     console.log('arr===',arr,i)
                                                //     if(arr[i].y-(arr[i].height/2)<scrollY){   //当滚动到超过当前盒子一半的时候
                                                //         // console.log('id===',arr[i].id)
                                                //         this.setState({curIndex:i})
                                                //     }
                                                // }
                                            }
                                        }
                                    )}>
                    {
                        this.state.scrollContentArr.map((item,id)=>{
                            return(
                                <View
                                    key={id}
                                    onLayout={({nativeEvent:e})=>this.layout(e,id)}   //传入 下标id
                                    style={{backgroundColor:'#fcf',flex:1,}}>
                                    <Text
                                        ref={ref => this.textRef = ref}
                                        style={{fontSize:16,color:'#0B0B34',fontWeight:'bold',backgroundColor:'red',height:30}}>
                                        {item.name}
                                    </Text>
                                    {
                                        [1,2,3,4,5].map((item1,id)=>{
                                            return(
                                                <View key={id} style={{flexDirection:'row',alignItems:'center',height:50,borderWidth:1}}>
                                                    <View style={{position: 'relative'}}>
                                                        <Text style={{fontSize:20}}>〇</Text>
                                                        <Text style={{position: 'absolute',left:6,top:4}}>1</Text>
                                                    </View>
                                                    <Text style={{marginLeft: 8,color:'#0B0B34',fontSize:14}}>{item.name}</Text>
                                                </View>
                                            )
                                        })
                                    }
                                </View>

                            )
                        })

                    }


                </ScrollView>
图片.png

获取滚动内容里每个元素的距离顶部的高度(即y值)、元素本身的高度、顺便给他一个id(用于后面方便找到这个元素),,并用空数组arr存起来

    layout = (e,id)=>{
        // console.warn('盒子高度',e,id)
        arr.push({y:e.layout.y,height:e.layout.height,id:id})
        console.warn('盒子高度2',arr)
    }
图片.png

2、点击导航栏定位到对应的元素

<ScrollView showsVerticalScrollIndicator={false}>
                    {
                        this.state.scrollContentArr.map((item,id)=>{
                            return(
                                <TouchableOpacity
                                    onPress={()=>this.handleLocation(id)}  //点击定位到与id下标对应的元素
                                    key={id}
                                    style={{justifyContent:'center',alignItems:'center'}}>
                                    <Text style={{backgroundColor:curIndex === id?'#0000FF':'#eee',fontSize:13,letterSpacing:12,paddingTop:4,paddingBottom:4}}>{item.name}</Text>
                                </TouchableOpacity>
                            )
                        })
                    }
                    </ScrollView>

    handleLocation(id){
        console.warn('当前文本的属性',this.scrollView,arr[id].y)  
        this.scrollView.scrollTo({x: 0, y: arr[id].y, animated: true})   //arr 就是之前定义的arr
    }

例子代码:

    _renderContent(){
        let curIndex = this.state.curIndex
        return(
            <View style={{paddingHorizontal:15,flexDirection:'row',backgroundColor:'red',height:Util.size.height-355}}>
                <ScrollView showsVerticalScrollIndicator={false}
                            ref={scrollView => this.scrollView = scrollView}
                            onScroll={Animated.event(
                                    [{ nativeEvent: {contentOffset: { y: 0 }}}],  //初始化滚动的距离
                                    { listener: (event) => {
                                        console.log('获取滚动的距离',event.nativeEvent.contentOffset.y)
                                            let scrollY = event.nativeEvent.contentOffset.y
                                            for(let i=0;i<arr.length;i++){
                                                if(arr[i].y-(arr[i].height/2)<scrollY){   //当滚动到超过当前盒子一半的时候
                                                    this.setState({curIndex:arr[i].id})
                                                }
                                            }
                                        }
                                    }
                            )}>
                    {
                        this.state.scrollContentArr.map((item,id)=>{
                            return(
                                <View
                                    key={id}
                                    onLayout={({nativeEvent:e})=>this.layout(e,id)}
                                    style={{backgroundColor:'#fcf',flex:1,}}>
                                    <Text
                                        ref={ref => this.textRef = ref}
                                        style={{fontSize:16,color:'#0B0B34',fontWeight:'bold',backgroundColor:'red',height:30}}>
                                        {item.name}
                                    </Text>
                                    {
                                        [1,2,3,4,5].map((item1,id)=>{
                                            return(
                                                <View key={id} style={{flexDirection:'row',alignItems:'center',height:50,borderWidth:1}}>
                                                    <View style={{position: 'relative'}}>
                                                        <Text style={{fontSize:20}}>〇</Text>
                                                        <Text style={{position: 'absolute',left:6,top:4}}>1</Text>
                                                    </View>
                                                    <Text style={{marginLeft: 8,color:'#0B0B34',fontSize:14}}>{item.name}</Text>
                                                </View>
                                            )
                                        })
                                    }
                                </View>

                            )
                        })

                    }


                </ScrollView>

                <View style={{width:50}}>
                    <ScrollView showsVerticalScrollIndicator={false}>
                    {
                        this.state.scrollContentArr.map((item,id)=>{
                            return(
                                <TouchableOpacity
                                    onPress={()=>this.handleLocation(id)}
                                    key={id}
                                    style={{justifyContent:'center',alignItems:'center'}}>
                                    <Text style={{backgroundColor:curIndex === id?'#0000FF':'#eee',fontSize:13,letterSpacing:12,paddingTop:4,paddingBottom:4}}>{item.name}</Text>
                                </TouchableOpacity>
                            )
                        })

                    }
                    </ScrollView>
                </View>

            </View>
        )
    }

调用

    render() {
        return (
            <View>
                <ImageBackground
                    source={require('../../YGYM_app/images/my/userBg.png')}
                    style={{height:200,width:Util.size.width}}>
                    {this.safeHeader()}
                    {this.showUserInfo(role_name)}
                </ImageBackground>
                {this._renderNav()}
                {/*调用滚动视图*/}
                {this._renderContent()}
            </View>
        )
    }

相关文章

网友评论

      本文标题:react-native 使用ScrollView实现滚动定位以

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