如何在 RN 平面列表中获取当前可见的索引
How to get currently visible index in RN flat list
我有一个水平平面列表,其中每个项目都是 width:300
我要做的就是获取当前可见项目的索引。
<FlatList
onScroll={(e) => this.handleScroll(e)}
horizontal={true}
data={this.state.data}
renderItem...
试过这个:
handleScroll(event) {
let index = Math.ceil(
event.nativeEvent.contentOffset.x / 300
);
还有这样的东西:
handleScroll(event) {
let contentOffset = event.nativeEvent.contentOffset;
let index = Math.floor(contentOffset.x / 300);
但没有什么是准确的我总是得到一个索引向上或向下一个索引。
我做错了什么以及如何在平面列表中获得正确的当前索引?
例如,我列出了列表中第 8 位的项目,但我得到的索引是 9 或 10。
UPD。感谢 @ch271828n 指出不应更新 onViewableItemsChanged
你可以使用 FlatList onViewableItemsChanged
属性来获得你想要的东西。
class Test extends React.Component {
onViewableItemsChanged = ({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration", changed);
}
render () => {
return (
<FlatList
onViewableItemsChanged={this.onViewableItemsChanged }
viewabilityConfig={{
itemVisiblePercentThreshold: 50
}}
/>
)
}
}
viewabilityConfig
可以帮助您随心所欲地设置可见度。在代码示例中,50
表示如果该项目的可见度超过 50%,则该项目被视为可见。
可以找到配置结构here
this.handleScroll = (event) => {
let yOffset = event.nativeEvent.contentOffset.y
let contentHeight = event.nativeEvent.contentSize.height
let value = yOffset / contentHeight
}
<FlatList onScroll={this.handleScroll} />
获取舍入值以计算 page-number/index。
非常感谢投票最多的答案:) 但是,当我尝试它时它不起作用,并引发错误说 changing onViewableItemsChanged on the fly is not supported
。经过一番搜索,我找到了解决方案here。这是可以 运行 没有错误的完整代码。关键是这两个配置应该放在 class properties 而不是在 render() 函数中。
class MyComponent extends Component {
_onViewableItemsChanged = ({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration", changed);
};
_viewabilityConfig = {
itemVisiblePercentThreshold: 50
};
render() {
return (
<FlatList
onViewableItemsChanged={this._onViewableItemsChanged}
viewabilityConfig={this._viewabilityConfig}
{...this.props}
/>
</View>
);
}
}
与@fzyzcjy 和@Roman 的回答相关。在 React 中,16.8+ 可以使用 useCallback
来处理 changing onViewableItemsChanged on the fly is not supported
错误。
function MyComponent(props) {
const _onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration", changed);
}, []);
const _viewabilityConfig = {
itemVisiblePercentThreshold: 50
}
return <FlatList
onViewableItemsChanged={_onViewableItemsChanged}
viewabilityConfig={_viewabilityConfig}
{...props}
/>;
}
在您的情况下,我想您可能会忽略项目的 padding
或 margin
。 contentOffsetX
或 contentOffsetY
应该是 firstViewableItemIndex
* (itemWidth
+ item padding or margin
)。
与其他答案一样,onViewableItemsChanged
将是满足您要求的更好选择。我写了一篇关于如何使用它以及它是如何实现的文章。
https://suelan.github.io/2020/01/21/onViewableItemsChanged/
有点晚了,但对我来说功能组件是不同的...
如果您使用的是功能组件,请这样做:
const onScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
const slideSize = event.nativeEvent.layoutMeasurement.width;
const index = event.nativeEvent.contentOffset.x / slideSize;
const roundIndex = Math.round(index);
console.log("roundIndex:", roundIndex);
}, []);
然后在你的 FlatList 上
<FlatList
data={[2, 3]}
horizontal={true}
pagingEnabled={true}
style={{ flex: 1 }}
showsHorizontalScrollIndicator={false}
renderItem={renderItem}
onScroll={onScroll}
/>
我有一个水平平面列表,其中每个项目都是 width:300
我要做的就是获取当前可见项目的索引。
<FlatList
onScroll={(e) => this.handleScroll(e)}
horizontal={true}
data={this.state.data}
renderItem...
试过这个:
handleScroll(event) {
let index = Math.ceil(
event.nativeEvent.contentOffset.x / 300
);
还有这样的东西:
handleScroll(event) {
let contentOffset = event.nativeEvent.contentOffset;
let index = Math.floor(contentOffset.x / 300);
但没有什么是准确的我总是得到一个索引向上或向下一个索引。
我做错了什么以及如何在平面列表中获得正确的当前索引?
例如,我列出了列表中第 8 位的项目,但我得到的索引是 9 或 10。
UPD。感谢 @ch271828n 指出不应更新 onViewableItemsChanged
你可以使用 FlatList onViewableItemsChanged
属性来获得你想要的东西。
class Test extends React.Component {
onViewableItemsChanged = ({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration", changed);
}
render () => {
return (
<FlatList
onViewableItemsChanged={this.onViewableItemsChanged }
viewabilityConfig={{
itemVisiblePercentThreshold: 50
}}
/>
)
}
}
viewabilityConfig
可以帮助您随心所欲地设置可见度。在代码示例中,50
表示如果该项目的可见度超过 50%,则该项目被视为可见。
可以找到配置结构here
this.handleScroll = (event) => {
let yOffset = event.nativeEvent.contentOffset.y
let contentHeight = event.nativeEvent.contentSize.height
let value = yOffset / contentHeight
}
<FlatList onScroll={this.handleScroll} />
获取舍入值以计算 page-number/index。
非常感谢投票最多的答案:) 但是,当我尝试它时它不起作用,并引发错误说 changing onViewableItemsChanged on the fly is not supported
。经过一番搜索,我找到了解决方案here。这是可以 运行 没有错误的完整代码。关键是这两个配置应该放在 class properties 而不是在 render() 函数中。
class MyComponent extends Component {
_onViewableItemsChanged = ({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration", changed);
};
_viewabilityConfig = {
itemVisiblePercentThreshold: 50
};
render() {
return (
<FlatList
onViewableItemsChanged={this._onViewableItemsChanged}
viewabilityConfig={this._viewabilityConfig}
{...this.props}
/>
</View>
);
}
}
与@fzyzcjy 和@Roman 的回答相关。在 React 中,16.8+ 可以使用 useCallback
来处理 changing onViewableItemsChanged on the fly is not supported
错误。
function MyComponent(props) {
const _onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration", changed);
}, []);
const _viewabilityConfig = {
itemVisiblePercentThreshold: 50
}
return <FlatList
onViewableItemsChanged={_onViewableItemsChanged}
viewabilityConfig={_viewabilityConfig}
{...props}
/>;
}
在您的情况下,我想您可能会忽略项目的 padding
或 margin
。 contentOffsetX
或 contentOffsetY
应该是 firstViewableItemIndex
* (itemWidth
+ item padding or margin
)。
与其他答案一样,onViewableItemsChanged
将是满足您要求的更好选择。我写了一篇关于如何使用它以及它是如何实现的文章。
https://suelan.github.io/2020/01/21/onViewableItemsChanged/
有点晚了,但对我来说功能组件是不同的...
如果您使用的是功能组件,请这样做:
const onScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
const slideSize = event.nativeEvent.layoutMeasurement.width;
const index = event.nativeEvent.contentOffset.x / slideSize;
const roundIndex = Math.round(index);
console.log("roundIndex:", roundIndex);
}, []);
然后在你的 FlatList 上
<FlatList
data={[2, 3]}
horizontal={true}
pagingEnabled={true}
style={{ flex: 1 }}
showsHorizontalScrollIndicator={false}
renderItem={renderItem}
onScroll={onScroll}
/>