使用 Animated.Flatlist 和 Animated.ScrollView 为 Animated.View 设置动画效果不流畅

Posted

技术标签:

【中文标题】使用 Animated.Flatlist 和 Animated.ScrollView 为 Animated.View 设置动画效果不流畅【英文标题】:Using Animated.Flatlist and Animated.ScrollView to animate an Animated.View is not smooth 【发布时间】:2018-02-11 20:11:07 【问题描述】:

我想做一个动画标题。

    我创建了一个 FlatList 的动画组件, 使用onScroll 函数更新动画值。 使用绝对位置将视图 (Animated.View) 作为动画 FlatList 上方的标题。 最后,使用变换属性插入动画值以更改视图 (Animated.View)。

动画效果很好,但动画一点都不流畅。

我saw this issue 如何使用scrollEventThrottle 有助于平滑。所以我认为使用 FlatList 会很顺利,但事实并非如此。如果按下时滚动,则很流畅。但是如果你滚动并离开手指,它会很跳跃(我不知道如何描述它。对不起)。滚动很流畅,但动画视图(标题)动画一点也不流畅。

环境

反应:16.0.0-alpha.12, 反应原生:^0.47.0, 节点:v7.7.3 npm: 4.1.2 纱线:0.21.3

目标平台: iosandroid

构建工具:博览会

Link to snack demo

export default class AnimatedHeader extends React.Component 
	state = 
		animatedValue: new Animated.Value(0),
	;
	
	_renderItem = (item) => 
		return (
			<View style=styles.nonsenseItem>
				<Text style=styles.itemText>item</Text>
			</View>
		)
	;
	
	render() 
		let scaleY = this.state.animatedValue.interpolate(
			inputRange: [0, 180],
			outputRange: [1, 0.5],
			extrapolate: 'clamp',
		);
		
		let translateY = this.state.animatedValue.interpolate(
			inputRange: [0, 180],
			outputRange: [0, -100],
			extrapolate: 'clamp',
		);
		
		return (
			<View style=styles.container>
				<AnimatedFlatList
					contentContainerStyle=marginTop: 200
					scrollEventThrottle=16 // <-- Use 1 here to make sure no events are ever missed
					onScroll=Animated.event(
						[nativeEvent: contentOffset: y: this.state.animatedValue],
						useNativeDriver: true // <-- Add this
					)
					data=data
					renderItem=this._renderItem
					keyExtractor=(item, i) => i/>
				<Animated.View style=[styles.headerWrapper, transform: [scaleY, translateY]]/>
			</View>
		)
	

更新

所以,我尝试使用 ScrollView 实现相同的功能。但是,我认为,与 FlatList 相比,使用 ScrollView 的情况更糟。

Here is the expo snack demo: Animated ScrollView Header

我想我首先需要提一下我是如何来到这里的。所以,我尝试通过一个非常好的tutorial in Medium 来实现这一点,并且还通过观看这个awesome youtube react conf viedo by Brent。但是,youtube 视频上使用的确切代码具有相同的效果。另外,在 Medium 教程中,作者给了他的expo Animated header link 的链接,运行非常顺利。但是当我复制粘贴代码时,相同的代码无法顺利运行。所以,我认为问题在于反应或反应本机版本。如果我有任何新的更新,我会更新。谢谢。

【问题讨论】:

有趣,在我看来,无论是按住还是滑动时,它都非常平滑(就像原生平滑一样)。我在运行 10.3.3 的 iPhone 7 上……你在用什么硬件?请注意,预览具有您所描述的行为,但主要是它在真实硬件上的表现...... 确实很有趣...可以确认在三星 S8 Android 设备上运行附加的 Snack 时会出现此问题,并且仅在滑动后应用动量时,而不是在用手指跟踪时。支持原生滚动视图如何发布事件似乎是一个潜在问题。 可能值得注意的是,scrollEventThrottle 未在 Android 上实现,因此调整该参数无济于事。 此外,Animated.event useNativeDriver 优化似乎在与 FlatList 一起使用时不会做任何事情,因为底层的 VirtualizedList 实现包装了它并在 JS 端的每个事件上手动调用它,这可以解释与标准 ListView/ScrollView 相比的去优化...github.com/facebook/react-native/blob/… 注意(此时主要是自我 :),似乎只发生在 Animated.ScrollView 上。有趣的是,在这个例子中使用 useNativeDriver: false 实际上在我的 S8 上产生了更好的性能:snack.expo.io/HJYtCsFtb 【参考方案1】:

React Native 0.46 中有一个回归,幸运的是,它已在 0.48.2 中得到修复(请参阅 this issue 和 this PR)。这就是为什么您在最近的 Expo 版本中遇到问题的原因。我在使用自定义视差图像时遇到了这个问题,通过使用 RN 0.48.3 构建自定义二进制文件解决了这个问题。

您的代码很好,尽管我建议将 scrollEventThrottle 设置为 1,因为这确实有助于在 iOS 上解决问题。

【讨论】:

是的,我发布了那个问题。您是否在您的 Android 设备中确认了该问题? 当然,我在 Android 上遇到过这个问题,RN 0.48.3 解决了它。你还在经历吗? 不,实际上我使用的是 expo 而不是 react native init。而且expo最新的SDK还是用的RN 0.47版本所以我现在也说不上来了。 我刚刚在最新版本的 Expo(1.2.0,基于 RN 0.48)中尝试了您的初始示例,对我来说一切看起来都很顺利。似乎回归已在0.48.2 中得到正确修复。

以上是关于使用 Animated.Flatlist 和 Animated.ScrollView 为 Animated.View 设置动画效果不流畅的主要内容,如果未能解决你的问题,请参考以下文章

JN5169 基于 JN-AN-1217 组网点灯

the/an/a用法及区别

Adobe Animate(An)2023软件安装包下载及安装教程

使用 PHAssets 时出现此错误:Creating an image format with an unknown type is an error

SpringBoot自定义注解和@Service("..")启动异常报错,Specified class is an interface,求解

烽火AN5506-01-B联通光纤猫设置方法