React Native里怎么让FlatList滚动到指定位置?
我在用FlatList展示一个很长的列表,想在某个操作后自动滚动到特定的item,试了scrollToIndex但一直报错说“scrollToIndex should be used in conjunction with getItemLayout”。
我加上getItemLayout之后还是不行,不知道是不是写错了。比如我想滚动到index为5的位置,代码是这样写的:
const flatListRef = useRef(null);
const scrollToItem = () => {
flatListRef.current?.scrollToIndex({ index: 5, animated: true });
};
const getItemLayout = (data, index) => ({
length: 80,
offset: 80 * index,
index,
});
但有时候能滚,有时候直接没反应,甚至崩溃。到底该怎么正确实现啊?
你写的 getItemLayout 里写死了 length: 80,但如果 item 实际高度不是 80(比如内容有动态文字、图片、不同样式),那 offset 就算错了,滚动位置自然不准,甚至触发内部状态错乱。
推荐的做法是:
要么所有 item 高度固定,且 getItemLayout 里的 length 必须等于你实际渲染的 item 高度(包括 padding、margin 都算进去),要么用 onLayout 动态测高。
举个最稳妥的固定高度写法(假设你每个 item 真的就是 80 高):
但要注意:
1. FlatList 必须在渲染时就确定好 item 高度,不能依赖异步加载(比如图片还没加载完就滚,高度就不准了)
2. 如果你用了 SectionList、有 header/footer、或者不同类型的 item 高度不一致,那 getItemLayout 就得按类型分别计算,不能硬编码
3. 如果真要动态高度,可以用 VirtualizedList 的 onLayout 测,但 FlatList 不推荐这么干,性能和稳定性都差
另外,你试过 scrollToOffset 吗?有时候直接算好 offset 滚更稳:
不过前提是 item 高度真的固定。要是你 item 高度不统一,那最好还是统一高度,或者换 FlatList 的 horizontal 模式以外的其他方案,比如 SectionList + stickyHeaderIndices,或者干脆自己用 FlatList + SectionList 拼一个。