From 2f6f1968b0027988641bba47afddb26f0db0e408 Mon Sep 17 00:00:00 2001 From: outaTiME Date: Mon, 10 Apr 2023 21:35:46 -0300 Subject: [PATCH 1/2] more reliable event handling between pan gesture and FlatList --- src/components/DraggableFlatList.tsx | 7 ++++++- src/context/refContext.tsx | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/DraggableFlatList.tsx b/src/components/DraggableFlatList.tsx index d7d98c27..93bb0b87 100644 --- a/src/components/DraggableFlatList.tsx +++ b/src/components/DraggableFlatList.tsx @@ -59,6 +59,7 @@ function DraggableFlatListInner(props: DraggableFlatListProps) { keyToIndexRef, propsRef, animationConfigRef, + panRef, } = useRefs(); const { activeCellOffset, @@ -264,9 +265,11 @@ function DraggableFlatListInner(props: DraggableFlatListProps) { const gestureDisabled = useSharedValue(false); const panGesture = Gesture.Pan() + .withRef(panRef) .onBegin((evt) => { gestureDisabled.value = disabled.value; if (gestureDisabled.value) return; + runOnJS(reset)(); panGestureState.value = evt.state; }) .onUpdate((evt) => { @@ -386,7 +389,9 @@ function DraggableFlatListInner(props: DraggableFlatListProps) { keyExtractor={keyExtractor} onScroll={scrollHandler} scrollEventThrottle={16} - simultaneousHandlers={props.simultaneousHandlers} + simultaneousHandlers={([panRef] as React.Ref[]).concat( + props.simultaneousHandlers ?? [] + )} removeClippedSubviews={false} /> {!!props.onScrollOffsetChange && ( diff --git a/src/context/refContext.tsx b/src/context/refContext.tsx index ea21575c..39702580 100644 --- a/src/context/refContext.tsx +++ b/src/context/refContext.tsx @@ -1,6 +1,6 @@ import React, { useContext } from "react"; import { useMemo, useRef } from "react"; -import { FlatList } from "react-native-gesture-handler"; +import { FlatList, GestureType } from "react-native-gesture-handler"; import Animated, { WithSpringConfig } from "react-native-reanimated"; import { DEFAULT_PROPS } from "../constants"; import { useProps } from "./propsContext"; @@ -14,6 +14,7 @@ type RefContextValue = { containerRef: React.RefObject; flatlistRef: React.RefObject> | React.ForwardedRef>; scrollViewRef: React.RefObject; + panRef: React.MutableRefObject; }; const RefContext = React.createContext | undefined>( undefined @@ -63,6 +64,7 @@ function useSetupRefs({ const flatlistRefInternal = useRef>(null); const flatlistRef = flatListRefProp || flatlistRefInternal; const scrollViewRef = useRef(null); + const panRef = useRef(undefined); // useEffect(() => { // // This is a workaround for the fact that RN does not respect refs passed in @@ -85,6 +87,7 @@ function useSetupRefs({ keyToIndexRef, propsRef, scrollViewRef, + panRef, }), [] ); From 4b637740f1a0969b05cbb8ebead773f857b0d670 Mon Sep 17 00:00:00 2001 From: outaTiME Date: Wed, 2 Jul 2025 23:16:17 -0300 Subject: [PATCH 2/2] revert: upstream fix (#586) due to reorder flickering --- src/components/CellRendererComponent.tsx | 13 ++++++++++++- src/components/DraggableFlatList.tsx | 13 ++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/CellRendererComponent.tsx b/src/components/CellRendererComponent.tsx index e4e861a6..d7b833b7 100644 --- a/src/components/CellRendererComponent.tsx +++ b/src/components/CellRendererComponent.tsx @@ -4,6 +4,7 @@ import { LayoutChangeEvent, MeasureLayoutOnSuccessCallback, StyleProp, + StyleSheet, ViewStyle, } from "react-native"; import Animated, { @@ -162,7 +163,11 @@ function CellRendererComponent(props: Props) { ? itemLayoutAnimation : undefined } - style={[props.style, baseStyle, animStyle]} + style={[ + props.style, + baseStyle, + activeKey ? animStyle : styles.zeroTranslate, + ]} pointerEvents={activeKey ? "none" : "auto"} > {children} @@ -172,6 +177,12 @@ function CellRendererComponent(props: Props) { export default typedMemo(CellRendererComponent); +const styles = StyleSheet.create({ + zeroTranslate: { + transform: [{ translateX: 0 }, { translateY: 0 }], + }, +}); + declare global { namespace NodeJS { interface Global { diff --git a/src/components/DraggableFlatList.tsx b/src/components/DraggableFlatList.tsx index 3af04f63..181dd9f6 100644 --- a/src/components/DraggableFlatList.tsx +++ b/src/components/DraggableFlatList.tsx @@ -6,12 +6,7 @@ import React, { useRef, useState, } from "react"; -import { - ListRenderItem, - FlatListProps, - LayoutChangeEvent, - InteractionManager, -} from "react-native"; +import { ListRenderItem, FlatListProps, LayoutChangeEvent } from "react-native"; import { FlatList, Gesture, @@ -120,9 +115,6 @@ function DraggableFlatListInner(props: DraggableFlatListProps) { if (dataHasChanged) { // When data changes make sure `activeKey` is nulled out in the same render pass activeKey = null; - InteractionManager.runAfterInteractions(() => { - reset(); - }); } useEffect(() => { @@ -230,8 +222,7 @@ function DraggableFlatListInner(props: DraggableFlatListProps) { } onDragEnd?.({ from, to, data: newData }); - - setActiveKey(null); + reset(); } );