首页 > 解决方案 > React Native FlatList 中的卡片堆栈动画

问题描述

我正在尝试在 React Native 中实现以下卡片堆栈动画。

https://streamable.com/ba8z4

目前,我正在根据列表使用FlatList每个单独的卡片位置并为其设置动画。translateYscrollPosition

不幸的是,它仍然没有按预期工作,因为当我只希望最上面的卡移动直到它离开堆栈时,所有卡都在移动。

任何帮助将非常感激!

这是我的实现:

小吃:https ://snack.expo.io/@tijp/flatlist-animations-card-stack

import * as React from 'react';
import { Animated, Dimensions, FlatList, Text, View, StyleSheet } from 'react-native';

const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
const cards = [{
  key: 'Card 1',
  color: '#3498db',
}, {
  key: 'Card 2',
  color: '#2ecc71',
}, {
  key: 'Card 3',
  color: '#e74c3c',
}, {
  key: 'Card 4',
  color: '#f1c40f',
}]

const HEIGHT = Dimensions.get('window').height;
const CARD_HEIGHT = 200;
const TRANSLATE_Y = [
  HEIGHT - 280, // TranslateY of first card
  HEIGHT - CARD_HEIGHT - 245, // TranslateY of second card
  HEIGHT - CARD_HEIGHT - CARD_HEIGHT - 210, // TranslateY of third card
  HEIGHT - CARD_HEIGHT - CARD_HEIGHT - CARD_HEIGHT - 175, // TranslateY of fourth card
];

export default class App extends React.Component {
  state = { scroll: new Animated.Value(0) };

  renderCard = (index, card) => (
    <Animated.View style={{
      height: CARD_HEIGHT,
      backgroundColor: card.color,
      marginVertical: 10,
      borderRadius: 6,
      transform: [{
        translateY: this.state.scroll.interpolate({
          inputRange: [-1, 0, 900],
          outputRange: [TRANSLATE_Y[index], TRANSLATE_Y[index], 0],
        }),
      }],
    }}>
      <Text style={styles.cardTitle}>{card.key}</Text>
    </Animated.View>
  );

  render() {
    const { scroll } = this.state;

    return (
      <View style={styles.container}>
        <AnimatedFlatList
          data={cards}
          style={{ width: '100%' }}
          renderItem={({ index, item }) => this.renderCard(index, item)}
          onScroll={Animated.event(
            [{ nativeEvent: { contentOffset: { y: scroll }}}],
            { useNativeDriver: true },
          )}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: 40,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  cardTitle: {
    textAlign: 'center',
    color: '#fff',
    marginTop: 12,
    fontSize: 20,
    fontWeight: '800',
  }
});

标签: react-native

解决方案


推荐阅读