[英]Animated PanResponder created with functional component jumps animation even though .setOffset() is implemented
[英]How to setOffset for panResponder when using hooks?
我找到了一個代碼示例,演示了在 react native 中使用 panResponder 進行拖放操作。 您可以嘗試以下小吃中的代碼:
https://snack.expo.io/S14RvxJ_L
我面臨的問題是,如果您將物品放入放置區域,然后再觸摸它,位置會一直重置。
我希望用戶能夠將項目拖離放置區域而不會出現此問題。 再次澄清:您將項目拖到放置區域,它將被塗成紅色。 現在再次拖動該項目並嘗試拖動到您想要的任何位置,該位置將被重置。 我嘗試用鈎子設置圓圈的初始位置,嘗試在開始時用起始值設置手勢的 y0 和 x0。 到目前為止沒有成功。
到目前為止我發現的是,我可以在 onPanResponderGrant 中使用 pan.setOffset()。 但是由於鍋是用 useRef() 創建的,它是可變的,不能改變,或者更好的是我不知道如何。
我將如何以最好的方式實現這一目標?
import React from 'react';
import { StyleSheet, View, Text, Dimensions, Animated, PanResponder } from 'react-native';
export default function Drag() {
const dropZoneValues = React.useRef(null);
const pan = React.useRef(new Animated.ValueXY());
const [bgColor, setBgColor] = React.useState('#2c3e50');
const isDropZone = React.useCallback((gesture) => {
const dz = dropZoneValues.current;
return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height;
}, []);
const onMove = React.useCallback((_, gesture) => {
if (isDropZone(gesture)) setBgColor('red');
else setBgColor('#2c3e50');
}, [isDropZone]);
const setDropZoneValues = React.useCallback((event) => {
dropZoneValues.current = event.nativeEvent.layout;
});
const panResponder = React.useMemo(() => PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: Animated.event([null, {
dx : pan.current.x,
dy : pan.current.y
}], {
listener: onMove
}),
onPanResponderRelease: (e, gesture) => {
if (!isDropZone(gesture)) {
Animated.spring(
pan.current,
{toValue:{x:0,y:0}}
).start();
}
}
}), []);
return (
<View style={styles.mainContainer}>
<View
onLayout={setDropZoneValues}
style={[styles.dropZone, {backgroundColor: bgColor}]}
>
<Text style={styles.text}>Drop me here!</Text>
</View>
<View style={styles.draggableContainer}>
<Animated.View
{...panResponder.panHandlers}
style={[pan.current.getLayout(), styles.circle]}
>
<Text style={styles.text}>Drag me!</Text>
</Animated.View>
</View>
</View>
);
}
let CIRCLE_RADIUS = 36;
let Window = Dimensions.get('window');
let styles = StyleSheet.create({
mainContainer: {
flex: 1
},
dropZone: {
height : 100,
backgroundColor:'#2c3e50'
},
text : {
marginTop : 25,
marginLeft : 5,
marginRight : 5,
textAlign : 'center',
color : '#fff'
},
draggableContainer: {
position : 'absolute',
top : Window.height/2 - CIRCLE_RADIUS,
left : Window.width/2 - CIRCLE_RADIUS,
},
circle: {
backgroundColor : '#1abc9c',
width : CIRCLE_RADIUS*2,
height : CIRCLE_RADIUS*2,
borderRadius : CIRCLE_RADIUS
}
});
(代碼來自: https : //github.com/facebook/react-native/issues/25360#issuecomment-505241400 )
我終於解決了
你可以在這里看到結果: https : //snack.expo.io/Bky!LlqbI
您必須在 onPanResponderGrant 中使用 setOffset 和 setValue。 pan 是一個可變對象,但仍然可以使用 pan.current.setOffset() 或 pan.current.setValue() 進行更改。 最后,我必須將 pan.current.flattenOffset 添加到 onPanResponderRelease 以便在放置區中的下一次拖動時保留該位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.