React Native中如何点击索引项滚动到列表对应元素?
React Native 上下列表联动滚动实现方案
你之前的代码存在3个核心问题,导致联动失效:
- 下方列表区域没有用
ScrollView/FlatList这类可滚动组件包裹,本身不支持受控滚动,还错误使用了web端的div标签,React Native 没有这个原生组件,运行会直接报错 - 没有记录每个列表项相对于滚动容器的Y轴偏移位置,点击事件里调用的
focus()是输入框组件的方法,根本不具备滚动定位能力 - 用普通变量存储选中的字母值不会触发视图更新,ref也没有和对应列表项做一一绑定
不需要依赖第三方库,用React Native原生提供的API就能稳定实现这个效果,具体实现代码如下:
实现代码
import { View, Text, TouchableOpacity, ScrollView } from 'react-native'; import { useRef } from 'react'; // 业务数据 const letterList = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}]; export default function LinkScrollDemo() { // 滚动容器ref const scrollContainerRef = useRef(null); // 存储每个列表项对应的Y轴偏移量 const itemOffsetMap = useRef({}); return ( <View style={{flex: 1}}> {/* 上方点击导航区域 */} <View style={{flexDirection: 'row', padding: 12, borderBottomWidth: 1, borderBottomColor: '#f0f0f0'}}> {letterList.map((item) => ( <TouchableOpacity key={item.name} style={{paddingHorizontal: 16, paddingVertical: 8}} onPress={() => { // 点击时滚动到对应项的位置 scrollContainerRef.current?.scrollTo({ y: itemOffsetMap.current[item.name], animated: true }) }} > <Text style={{fontSize: 16}}>{item.name}</Text> </TouchableOpacity> ))} </View> {/* 下方可滚动列表区域 */} <ScrollView ref={scrollContainerRef} style={{flex: 1}}> {letterList.map((item) => ( <View key={item.name} onLayout={(e) => { // 组件挂载/布局变化时,自动记录当前项的Y轴位置 itemOffsetMap.current[item.name] = e.nativeEvent.layout.y; }} style={{ minHeight: 240, padding: 24, borderBottomWidth: 1, borderBottomColor: '#f0f0f0' }} > <Text style={{fontSize: 28}}>{item.name}</Text> {/* 每个分类下的业务内容直接写在这里即可,动态高度也不影响定位 */} </View> ))} </ScrollView> </View> ) }
适配说明
- 如果下方列表用
FlatList实现,只需要把ScrollView替换成FlatList,将scrollTo方法换成scrollToOffset即可,位置测量逻辑完全不变 - 列表项高度动态变化时不需要额外处理,
onLayout会在布局更新时自动重新计算偏移量,定位不会出错 - 第三方滚动定位库本质也是封装了上述逻辑,直接用原生API没有额外依赖,版本兼容性更好,不会出现库维护不及时导致的失效问题
内容的提问来源于stack exchange,提问作者Louis
相关产品推荐
相关产品推荐

