首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当在FlatList中滑动到间隔时,如何检测哪个项目会被抢断到哪个项目?

当在FlatList中滑动到间隔时,如何检测哪个项目会被抢断到哪个项目?
EN

Stack Overflow用户
提问于 2019-08-23 22:56:42
回答 1查看 2K关注 0票数 7

我有一个具有水平<FlatList>的组件,该组件包含100多个项目(日历日),其宽度与屏幕相同。<FlatList>设置为与屏幕宽度类似的间隔,因此我可以在项之间滑动。

当我滑动到特定日期时,我想更新UI以显示该日期,在<FlatList>之上。现在,我正在使用onMomentumScrollEnd查找最终偏移量和标题中显示的日期项。

但是,用户体验并不是最优的,因为在滑动/滚动动画结束之前没有更新标头。

我需要的是一种方法,以确定哪个偏移,<FlatList>将快照,一旦用户滑动。

我想onScroll可能是有用的,但是根据我从onScroll得到的事件,我有点迷失在寻找下一个偏移量帽子的<FlatList>上。

但是,我可以看到像react-native-snap-carousel这样的第三方模块正在使用onScroll,所以我想这是可能的。

我选择不使用react-native-snap-carousel,因为它确实降低了屏幕上的滑动动画性能。如果模块没有给出明确的答案,查看代码,因为这个模块有很多我不需要的特性,这些特性是它用来确定下一个snapTo offSet的代码的一部分。

EN

回答 1

Stack Overflow用户

发布于 2021-10-03 17:03:43

要检测viewabilityConfig中的"snap“,可以使用FlatList和onViewableItemsChanged Flatlist属性。

请参阅下面的代码(关于Hooks组件),其中我在onViewChanged方法中处理"snap“:

代码语言:javascript
复制
import React, {useRef, useState} from 'react';
import {Dimensions, FlatList, View} from 'react-native';

// CLASS COMPONENT API
export class DemoViewabilityConfigClass extends React.Component {
  flatlistRef;
  constructor(props) {
    super(props);
    this.state = {
      activeIndex: 0,
    };
  }

  onViewChanged = ({viewableItems, index}) => {
    console.log('I snapped to', viewableItems);
    if (viewableItems.length > 0) {
      const {item: activeItem, index: activeIndex} = viewableItems[0];
      console.log(activeItem, activeIndex);
      this.setState({activeIndex: activeIndex});
    }
  };

  render() {
    return (
      <FlatList
        ref={ref => (this.flatlistRef = ref)}
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={{
          marginHorizontal: 10,
        }}
        snapToInterval={Dimensions.get('window').width}
        decelerationRate={0}
        overScrollMode={'never'}
        snapToAlignment={'center'}
        data={[
          {
            id: 'something',
            other: 'data',
          },
          {
            id: 'else',
            other: 'data',
          },
        ]}
        onScrollEndDrag={() => console.log('Scroll end')}
        horizontal={true}
        viewabilityConfig={{itemVisiblePercentThreshold: 70}}
        onViewableItemsChanged={this.onViewChanged}
        onScrollToIndexFailed={info => {
          console.log('Scroll failed', info);
          const wait = new Promise(resolve => setTimeout(resolve, 500));
          wait.then(() => {
            this.flatlistRef.current?.scrollToIndex({
              index: info.index,
              animated: true,
            });
          });
        }}
        renderItem={({item, index}) => {
          return (
            <View
              style={{
                marginRight: 20,
                height: 20,
                width: Dimensions.get('window').width - 20,
                backgroundColor: 'red',
              }}
            />
          );
        }}
      />
    );
  }
}

// HOOKS API
export function DemoViewabilityConfigHooks() {
  const flatlistRef = useRef(null);
  const [activeEventIndex, setActiveEventIndex] = useState(0);

  const onViewChanged = React.useRef(({viewableItems}) => {
    console.log('Items ', viewableItems);
    if (viewableItems.length > 0) {
      const {index, item} = viewableItems[0];
      console.log('Active index', index);
      setActiveEventIndex(index);
    }
  });

  const viewConfigRef = React.useRef({viewAreaCoveragePercentThreshold: 50});

  return (
    <FlatList
      ref={flatlistRef}
      showsHorizontalScrollIndicator={false}
      contentContainerStyle={{
        marginHorizontal: 10,
      }}
      snapToInterval={Dimensions.get('window').width}
      decelerationRate={0}
      overScrollMode={'never'}
      snapToAlignment={'center'}
      data={[
        {
          id: 'something',
          other: 'data',
        },
        {
          id: 'else',
          other: 'data',
        },
      ]}
      onScrollEndDrag={() => console.log('Scroll end')}
      horizontal={true}
      viewabilityConfig={viewConfigRef.current}
      onViewableItemsChanged={onViewChanged.current}
      onScrollToIndexFailed={info => {
        console.log('Scroll failed', info);
        const wait = new Promise(resolve => setTimeout(resolve, 500));
        wait.then(() => {
          flatlistRef.current?.scrollToIndex({
            index: info.index,
            animated: true,
          });
        });
      }}
      renderItem={({item, index}) => {
        return (
          <View
            style={{
              marginRight: 20,
              height: 20,
              width: Dimensions.get('window').width - 20,
              backgroundColor: 'red',
            }}
          />
        );
      }}
    />
  );
}

例如,如果需要在onViewChanged方法中更改组件状态,则在使用Functional / Hooks时,需要将这2个支持包到Ref()中。否则,会导致“不支持动态更改onViewableItemsChanged”。错误。此外,您还需要使用.current语法将这些道具传递给Flalist。

下面是GIF示例:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57633835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档