如果在两个组件中使用,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]}
>
在我当前的应用程序中,动画 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]}
>