如果在两个组件中使用,React Native Redash onScrollEvent 不会更改 Y 值

React Native Redash onScrollEvent not changing Y value if used in two components

在我当前的应用程序中,动画 y 值仅在我热重新加载我的应用程序后发生变化。

在重新加载应用程序之前,我的组件的 y 值没有改变,或者至少它没有插入 y 值

我不确定是什么原因导致了这种奇怪的现象。

这里是snippet的代码。

这里我创建动画Y值

import React from "react";
import { View, StyleSheet } from "react-native";
import Animated from "react-native-reanimated";
import ListHeader from "./ListHeader";
import ListBody from "./ListBody";

const { Value } = Animated;

 const TransitionList = ({ album }) => {
  const y = new Value(0);

  return (
    <View style={styles.container}>
       <ListHeader {...{ y, album }} />
      <ListBody {...{ y, album }} />
    </View>
  );
};

export default TransitionList

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "black",
  },
});

这里我改变了onScroll的Y值

import React from "react";
import styled from "styled-components";
import { StyleSheet, View } from "react-native";
import { onScrollEvent } from "react-native-redash";
import { LinearGradient } from "expo-linear-gradient";
import Animated from "react-native-reanimated";
import ListTitle from "./ListTitle";
import ListItem from "./ListItem";
import {
  MAX_HEADER_HEIGHT,
  MIN_HEADER_HEIGHT,
  BUTTON_HEIGHT,
} from "../helpers";

const { interpolate, Extrapolate } = Animated;

const ListBody = ({ album: { artist, tracks }, y }) => {
  const height = interpolate(y, {
    inputRange: [-MAX_HEADER_HEIGHT, -BUTTON_HEIGHT / 2],
    outputRange: [0, MAX_HEADER_HEIGHT + BUTTON_HEIGHT],
    extrapolate: Extrapolate.CLAMP,
  });
  const opacity = interpolate(y, {
    inputRange: [-MAX_HEADER_HEIGHT / 2, 0, MAX_HEADER_HEIGHT / 2],
    outputRange: [0, 1, 0],
    extrapolate: Extrapolate.CLAMP,
  });
  return (
    <Animated.ScrollView
      onScroll={onScrollEvent({ y })}
      style={styles.container}
      showsVerticalScrollIndicator={false}
      scrollEventThrottle={1} 
      stickyHeaderIndices={[1]}
    >
      <View style={styles.cover}>
        <Animated.View style={[styles.gradient, { height }]}>
          <LinearGradient
            style={StyleSheet.absoluteFill}
            start={[0, 0.3]}
            end={[0, 1]}
            colors={["transparent", "rgba(0, 0, 0, 0.2)", "black"]}
          />
        </Animated.View>
        <View style={styles.artistContainer}>
          <Animated.Text style={[styles.artist, { opacity }]}>
            {artist}
          </Animated.Text>
        </View>
      </View>
      <View style={styles.header}>
        <ListTitle {...{ y, artist }} />
      </View>
      <View style={styles.tracks}>
        {tracks.map((track, key) =>
          <ListItem index={key + 1} {...{ track, key, artist }} />
        )}
      </View>
    </Animated.ScrollView>
  );
};

export default ListBody


const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: MIN_HEADER_HEIGHT - BUTTON_HEIGHT / 2,
  },
  cover: {
    height: MAX_HEADER_HEIGHT - BUTTON_HEIGHT,
  },
  gradient: {
    position: "absolute",
    left: 0,
    bottom: 0,
    right: 0,
    alignItems: "center",
  },
  artistContainer: {
    ...StyleSheet.absoluteFillObject,
    justifyContent: "center",
    alignItems: "center",
  },
  artist: {
    textAlign: "center",
    color: "white",
    fontSize: 48,
    fontWeight: "bold",
  },
  header: {
    marginTop: -BUTTON_HEIGHT,
  },
  tracks: {
    paddingTop: 32,
    backgroundColor: "black",
  },
});

这里Y值的变化应该也发生在这个组件上

import React from "react";
import Animated from "react-native-reanimated";
import { Image, StyleSheet } from "react-native";

import { MAX_HEADER_HEIGHT, HEADER_DELTA, BUTTON_HEIGHT } from "../helpers";

const { interpolate, Extrapolate } = Animated;

const ListHeader = ({ album: { cover }, y }) => {
  const scale = interpolate(y, {
    inputRange: [-MAX_HEADER_HEIGHT, 0],
    outputRange: [4, 1],
    extrapolateRight: Extrapolate.CLAMP,
  });
  const opacity = interpolate(y, {
    inputRange: [-64, 0, HEADER_DELTA],
    outputRange: [0, 0.2, 1],
    extrapolate: Extrapolate.CLAMP,
  });

  return (
    <Animated.View style={[styles.container, { transform: [{ scale }] }]}>
      <Image style={styles.image} source={cover} />
      <Animated.View
        style={{
          ...StyleSheet.absoluteFillObject,
          backgroundColor: "black",
          opacity,
        }}
      />
    </Animated.View>
  );
};

export default ListHeader


const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFillObject,
    height: MAX_HEADER_HEIGHT + BUTTON_HEIGHT * 2,
  },
  image: {
    ...StyleSheet.absoluteFillObject,
    width: undefined,
    height: undefined,
  },
});

我通过删除 reanimated 和 react-native-redash 库并使用 RN 自己的 Animated 库来修复它

示例如下:

const TransitionList = ({
  album,
  children,
  image,
  title,
  sub,
  list,
  header,
}) => {
  const [scrollY, setScrollY] = useState(new Animated.Value(0));


  return (
    <Container SCREEN_HEIGHT={SCREEN_HEIGHT} ThemeColors={ThemeColors}>
      <ListHeader y={scrollY} album={album} image={image} />
      <ListBody
        setY={setScrollY}
        y={scrollY}
        album={album}
        title={title}
        sub={sub}
        header={header}
        list={list}
      >
        {children}
      </ListBody>
    </Container>
  );
};
<Animated.ScrollView
      onScroll={event =>
        setY(new Animated.Value(event.nativeEvent.contentOffset.y))}
      style={styles.container}
      showsVerticalScrollIndicator={false}
      scrollEventThrottle={1}
      stickyHeaderIndices={[1]}
    >