用例
我需要利用PanResponder用手指移动视图。一旦手指从屏幕上抬起,视图应该以动量保持在移动方向上移动,并以减速的速度停止。
问题
我可以使用Animated.decay方法实现用例onPanResponderRelease
。但是当我再次开始移动视图时,它会捕捉到与其位置的偏移量。
我pan.flattenOffset()
按照 PanResponder 文档中的示例进行了尝试,但这没有帮助。只要我不使用Animated.decay方法,它就可以工作。
onPanResponderRelease: (_, { vx, vy }) => {
// pan.flattenOffset() alone works but then there's no momentum on release
Animated.parallel([
Animated.decay(pan.x, {
velocity: vx,
useNativeDriver: true,
}),
Animated.decay(pan.y, {
velocity: vy,
useNativeDriver: true,
}),
]).start(() => pan.flattenOffset()); // pan.flattenOffset doesn’t work here
},
显示有和没有动量运动的 GIF
代码
import React, { useRef } from 'react';
import {
View,
Animated,
StyleSheet,
PanResponder,
SafeAreaView,
} from 'react-native';
const App = () => {
const pan = useRef(new Animated.ValueXY()).current;
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => pan.setOffset({ x: pan.x._value, y: pan.y._value }),
onPanResponderMove: Animated.event(
[null, { dx: pan.x, dy: pan.y }],
{ useNativeDriver: false },
),
// this alone works
// onPanResponderRelease: () => {
// pan.flattenOffset();
// },
onPanResponderRelease: (_, { vx, vy }) => {
Animated.parallel([
Animated.decay(pan.x, {
velocity: vx,
useNativeDriver: true,
}),
Animated.decay(pan.y, {
velocity: vy,
useNativeDriver: true,
}),
]).start(() => pan.flattenOffset()); // pan.flattenOffset doesn’t work here
},
}),
).current;
return (
<SafeAreaView style={styles.container}>
<Animated.View
style={[{ transform: [{ translateX: pan.x }, { translateY: pan.y }] }]}
{...panResponder.panHandlers}
>
<View style={[styles.point]} />
</Animated.View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
point: {
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: '#000',
},
});
export default App;