コメントのリストがあり、それらのコメントをドラッグ アンド ドロップして並べ替えたいと考えています。リストは次のようになります: https://i.stack.imgur.com/sozkK.png
私の問題は、ユーザーがコメントをドラッグしているときにアイテムがある場所に「プレビュー」を表示したいということです。そのため、アイテムがリストの別のアイテムにドラッグされるたびに、それら2つを入れ替えてリストを並べ替えますしかし次に、現在ドラッグされているアイテムが、ドラッグしているアイテムに変わります。配列 ["a","b","c"] があるとします。A をドラッグして B の上に移動すると、ドラッグしている項目が B に変換されます (B が最初の位置にあるため)。配列)。私が望むのは、ドラッグされているアイテムがそこにドロップされた場合にリストがどのように見えるかのプレビューを簡単に表示することです
これは私のコンポーネントです:
import React, { useState, useEffect, useRef, useMemo, View } from "react";
import { StyleSheet, Animated, PanResponder } from "react-native";
const Draggable = ({
index,
position,
movingDraggable,
onMovingDraggable,
releaseDraggable,
onReleaseDraggable,
swap,
renderChild
}) => {
const animatedView = useRef();
const [zIndex, setZIndex] = useState(0);
const [isMovedOver, setIsMovedOver] = useState(false);
useEffect(() => {
animatedView.current.measure((x, y, width, height, pageX, pageY) => {
if (
movingDraggable &&
movingDraggable.index != index &&
movingDraggable.pageX > pageX &&
movingDraggable.pageX < pageX + width &&
movingDraggable.pageY > pageY &&
movingDraggable.pageY < pageY + height
) {
setIsMovedOver(true);
swap(index, movingDraggable.index);
} else {
setIsMovedOver(false);
}
});
}, [movingDraggable]);
useEffect(() => {
animatedView.current.measure((x, y, width, height, pageX, pageY) => {
if (
releaseDraggable &&
releaseDraggable.index != index &&
releaseDraggable.pageX > pageX &&
releaseDraggable.pageX < pageX + width &&
releaseDraggable.pageY > pageY &&
releaseDraggable.pageY < pageY + height
) {
swap(index, releaseDraggable.index);
}
});
}, [releaseDraggable]);
const pan = useRef(new Animated.ValueXY());
const panResponder = useMemo(
() =>
PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
setZIndex(1);
pan.current.setOffset({
x: pan.current.x._value,
y: pan.current.y._value,
});
pan.current.setValue({ x: 0, y: 0 });
},
onPanResponderMove: Animated.event(
[null, { dx: pan.current.x, dy: pan.current.y }],
{
useNativeDriver: false,
listener: (evt) => {
const { pageX, pageY } = evt.nativeEvent;
onMovingDraggable({ index, pageX, pageY });
},
}
),
onPanResponderRelease: (evt, gestureState) => {
setZIndex(0);
const { pageX, pageY } = evt.nativeEvent;
onReleaseDraggable({ index, pageX, pageY });
setIsMovedOver(false);
Animated.spring(pan.current, {
toValue: {
x: 0 - pan.current.x._offset,
y: 0 - pan.current.y._offset,
},
useNativeDriver: false,
}).start(() => {
pan.current.setValue({ x: 0, y: 0 });
pan.current.setOffset({ x: 0, y: 0 });
});
},
}),
[]
);
const panStyle = { transform: pan.current.getTranslateTransform() };
return (
<Animated.View
{...panResponder.panHandlers}
ref={animatedView}
style={[panStyle, styles.shadow, position, { zIndex: zIndex }, /* zIndex ? { width: 0 } : null */ ]}
>
{renderChild(isMovedOver)}
</Animated.View>
)
};
const styles = StyleSheet.create({
shadow: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.1,
shadowRadius: 10,
elevation: 10,
},
});
export default Draggable
親の関数:
const onMovingDraggable = (movingDraggable) => {
setMovingDraggable(movingDraggable);
};
const onReleaseDraggable = (releaseDraggable) => {
setMovingDraggable(null);
setReleaseDraggable(releaseDraggable);
};
const swap = (index1, index2) => {
var arr = [...characteristics];
arr.splice(index1 + 1, 0, arr[index2])
arr.splice(index2, 1)
setCharacteristics(arr);
};