React Native:使用 react-native-reanimated 动画视图高度的性能不佳
React Native : Bad performance animating the height of a view using react-native-reanimated
滚动列表时动画视图的高度非常缓慢且不稳定,
它适用于 IOS,但不适用于 Android:
import * as React from "react";
import { StyleSheet, Text } from "react-native";
import Animated from "react-native-reanimated";
const { Value, View, ScrollView, interpolate, Extrapolate } = Animated;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "black"
},
listView: {
flex: 1
}
});
const IMAGE_MIN_HEIGHT = 300;
export default () => {
const animation = new Value(0);
const height = interpolate(animation, {
inputRange: [0, 125],
outputRange: [IMAGE_MIN_HEIGHT, 125],
extrapolate: Extrapolate.CLAMP
});
return (
<View style={styles.container}>
<View
style={{
backgroundColor: "red",
height: height,
width: "100%"
}}
></View>
<ScrollView
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
y: animation
}
}
}
])}
scrollEventThrottle={1}
style={[styles.listView]}
>
{[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].map((elem, index) => (
<View
style={{ width: "100%", height: 100, marginBottom: 20 }}
key={index}
>
<Text style={{ color: "white", fontSize: 30 }}>{elem}</Text>
</View>
))}
</ScrollView>
</View>
);
};
有什么办法可以让它更顺畅吗?
尝试为 Android 使用 NativeDriver。
此外,为了获得更好的性能,您应该在此处使用 FlatList or SectionList 而不是 ScrollView。
<Animated.ScrollView
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
y: animation
}
}
}
],
{ useNativeDriver: true } // Add this line
)}
scrollEventThrottle={1}
style={[styles.listView]}
>
//
</Animated.ScrollView>
详情请见this
解决方案是将页眉位置设置为绝对位置,我不知道为什么但它工作正常:
import * as React from "react";
import { StyleSheet, Text, Platform } from "react-native";
import Animated from "react-native-reanimated";
const { Value, View, ScrollView, interpolate, Extrapolate } = Animated;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "black"
},
listView: {
flex: 1
}
});
const IMAGE_MIN_HEIGHT = 300;
export default () => {
const animation = new Value(0);
const height = interpolate(animation, {
inputRange: [0, 125],
outputRange: [IMAGE_MIN_HEIGHT, 125],
extrapolate: Extrapolate.CLAMP
});
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={{ paddingTop: IMAGE_MIN_HEIGHT }}
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
y: animation
}
}
}
])}
scrollEventThrottle={1}
style={[styles.listView]}
>
{[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].map((elem, index) => (
<View
style={{ width: "100%", height: 100, marginBottom: 20 }}
key={index}
>
<Text style={{ color: "white", fontSize: 30 }}>{elem}</Text>
</View>
))}
</ScrollView>
<View
style={{
backgroundColor: "red",
height: height,
width: "100%",
position: "absolute",
top: Platform.OS == "ios" ? 20 : 0,
left: 0,
right: 0
}}
></View>
</View>
);
};
滚动列表时动画视图的高度非常缓慢且不稳定, 它适用于 IOS,但不适用于 Android:
import * as React from "react";
import { StyleSheet, Text } from "react-native";
import Animated from "react-native-reanimated";
const { Value, View, ScrollView, interpolate, Extrapolate } = Animated;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "black"
},
listView: {
flex: 1
}
});
const IMAGE_MIN_HEIGHT = 300;
export default () => {
const animation = new Value(0);
const height = interpolate(animation, {
inputRange: [0, 125],
outputRange: [IMAGE_MIN_HEIGHT, 125],
extrapolate: Extrapolate.CLAMP
});
return (
<View style={styles.container}>
<View
style={{
backgroundColor: "red",
height: height,
width: "100%"
}}
></View>
<ScrollView
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
y: animation
}
}
}
])}
scrollEventThrottle={1}
style={[styles.listView]}
>
{[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].map((elem, index) => (
<View
style={{ width: "100%", height: 100, marginBottom: 20 }}
key={index}
>
<Text style={{ color: "white", fontSize: 30 }}>{elem}</Text>
</View>
))}
</ScrollView>
</View>
);
};
有什么办法可以让它更顺畅吗?
尝试为 Android 使用 NativeDriver。
此外,为了获得更好的性能,您应该在此处使用 FlatList or SectionList 而不是 ScrollView。
<Animated.ScrollView
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
y: animation
}
}
}
],
{ useNativeDriver: true } // Add this line
)}
scrollEventThrottle={1}
style={[styles.listView]}
>
//
</Animated.ScrollView>
详情请见this
解决方案是将页眉位置设置为绝对位置,我不知道为什么但它工作正常:
import * as React from "react";
import { StyleSheet, Text, Platform } from "react-native";
import Animated from "react-native-reanimated";
const { Value, View, ScrollView, interpolate, Extrapolate } = Animated;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "black"
},
listView: {
flex: 1
}
});
const IMAGE_MIN_HEIGHT = 300;
export default () => {
const animation = new Value(0);
const height = interpolate(animation, {
inputRange: [0, 125],
outputRange: [IMAGE_MIN_HEIGHT, 125],
extrapolate: Extrapolate.CLAMP
});
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={{ paddingTop: IMAGE_MIN_HEIGHT }}
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
y: animation
}
}
}
])}
scrollEventThrottle={1}
style={[styles.listView]}
>
{[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].map((elem, index) => (
<View
style={{ width: "100%", height: 100, marginBottom: 20 }}
key={index}
>
<Text style={{ color: "white", fontSize: 30 }}>{elem}</Text>
</View>
))}
</ScrollView>
<View
style={{
backgroundColor: "red",
height: height,
width: "100%",
position: "absolute",
top: Platform.OS == "ios" ? 20 : 0,
left: 0,
right: 0
}}
></View>
</View>
);
};