使用 FlatList 时如何在 React Native 中自定义滚动和捕捉动画

问题描述 投票:0回答:1

平面列表中包含的每个项目的宽度等于屏幕宽度。当我向左或向右滑动时,我不喜欢自动捕捉动画效果。 具体来说,动画时长太短,有卡顿的感觉。

我尝试过使用内置的 flatlist 组件,例如“decelerationRate”和“snapToInterval”,但它们都没有达到预期的效果。 我也尝试过Reanimated库,但是找了很久文档,没有找到实现自定义动画的方法。 无论是Reanimated flatlist还是内置的flatlist的scrollTo方法,动画参数都只有“{animated: true}”等选项来切换动画,并没有办法调整时长。 如果你能帮助我,我将非常感激。我几天来一直在寻找解决方案。

android reactjs react-native react-native-flatlist react-native-reanimated
1个回答
0
投票

如果您没有任何边距/填充,并且

<FlatList />
上的每个项目的宽度相同,则只需传递
pagingEnabled
decelerationRate="fast"
snapToInterval
。但如果您有不同的项目宽度,您可能需要使用
snapToOffsets
(甚至
getItemLayout
)。

看看这个关于 Snack 的例子

无论如何,如果您想快速查看,这里是源代码。

import React from 'react';
import { Animated, View, SafeAreaView, Dimensions } from 'react-native';

const itemWidth = 300;
const itemHeight = 400;
const screenWidth = Dimensions.get('screen').width;
const marginHorizontal = (screenWidth - itemWidth) / 2;

const colors = ['blue', 'brown', 'pink', 'purple'];

export default function App() {
  const renderItem = React.useCallback(
    ({ item, index }: ListRenderItemInfo<RGBColor>) => {
      return (
        <View
          style={{
            height: itemHeight,
            width: itemWidth,
            backgroundColor: item,
            flex: 1,
          }}
        />
      );
    },
    []
  );
  const keyExtractor = React.useCallback(
    (data, index) => `${index}-${data}`,
    []
  );
  /** In case you want more granular control over the item width */
  const getItemLayout = React.useCallback(
    (_, index) => ({
      index,
      length: itemWidth,
      offset: itemWidth * index + marginHorizontal,
    }),
    []
  );
  const snapToOffsets = React.useMemo(
    () => colors.map((_, index) => itemWidth * (index + 1)),
    []
  );
  return (
    <SafeAreaView
      style={{
        flex: 1,
        justifyContent: 'center',
        backgroundColor: '#ecf0f1',
        height: itemHeight,
      }}>
      <Animated.FlatList
        style={{ marginVertical: 20, height: itemHeight }}
        contentContainerStyle={{
          alignItem: 'center',
          paddingHorizontal: marginHorizontal,
        }}
        pagingEnabled
        snapToOffsets={snapToOffsets}
        decelerationRate="fast"
        snapToInterval
        snapToAlignment="center"
        horizontal
        data={colors}
        showsHorizontalScrollIndicator={false}
        keyExtractor={keyExtractor}
        renderItem={renderItem}
        // getItemLayout={getItemLayout}
      />
      <View
        style={{
          position: 'absolute',
          top: 0,
          start: 0,
          end: 0,
          alignItems: 'center',
          justifyContent: 'center',
        }}
        pointerEvents="none">
        <SafeAreaView
          style={{
            marginVertical: 20,
            backgroundColor: 'rgba(255, 0, 0, 0.3)',
            height: itemHeight,
            width: itemWidth,
            flex: 1,
            borderWidth: 1,
            borderColor: 'green',
            borderRadius: 10,
          }}
        />
      </View>
    </SafeAreaView>
  );
}

FlatList with snap effect

© www.soinside.com 2019 - 2024. All rights reserved.