I’ve got it working in production with Expo’s GestureHandler (Android, iOS awaiting review but worked when testing in production mode) using the following setup:
My SwipeableList (note that I use FlatList from RN directly, the GestureHandler FlatList did not work for me). Also I am passing the function to be called when on the rightAction pressed in with the itemArray data:
import React, { Component } from 'react';
import {
FlatList,
StyleSheet,
} from 'react-native';
import { DangerZone } from 'expo';
const { GestureHandler } = DangerZone;
const { RectButton } = GestureHandler;
const Row = ({ item }) =>
<RectButton
style={styles.rectButton}
onPress={() => item.onPress()}
>
<BnListItem />
</RectButton>;
const SwipeableRow = ({ item }) => {
return (
<BnSwipeableRow
onDelete={item.onDelete}
>
<Row item={item} />
</BnSwipeableRow>
);
};
class BnSwipeableList extends Component {
render() {
return (
<FlatList
{...this.props}
keyExtractor={(item, index) => index}
renderItem={({ item, index }) =>
<SwipeableRow item={item} index={index} />}
/>
);
}
}
export { BnSwipeableList };
My SwipeableRow component:
import React, { Component } from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { DangerZone } from 'expo';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Swipeable from './Swipeable';
const { GestureHandler } = DangerZone;
const { RectButton } = GestureHandler;
const AnimatedIcon = Animated.createAnimatedComponent(Icon);
export default class BnSwipeableRow extends Component {
updateRef = ref => {
this._swipeableRow = ref;
};
close = () => {
this._swipeableRow.close();
};
renderRightActions = (progress, dragX) => {
const scale = dragX.interpolate({
inputRange: [-80, 0],
outputRange: [1, 0],
extrapolate: 'clamp',
});
return (
<View style={{ width: 90, flexDirection: 'row' }}>
<RectButton
style={styles.rightAction}
onPress={() => {
this.props.onDelete();
this.close();
}}
>
<AnimatedIcon
name="delete-forever"
size={30}
color="#fff"
style={[styles.actionIcon, { transform: [{ scale }] }]}
/>
</RectButton>
</View>
);
};
render() {
const { children } = this.props;
return (
<Swipeable
ref={this.updateRef}
friction={2}
rightThreshold={40}
renderRightActions={this.renderRightActions}
>
{children}
</Swipeable>
);
}
}
const styles = StyleSheet.create({
actionIcon: {
width: 30,
marginHorizontal: 10,
},
rightAction: {
alignItems: 'flex-end',
backgroundColor: '#dd2c00',
flex: 1,
justifyContent: 'center',
},
});
And finally my rendition of the Swipeable component from GestureHandler:
Into this file I just copied the Swipeable component from the GestureHandler Repo and replaced all imports from react-native-gesture-handler with importing from Expo DangerZone:
import React, { Component } from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { DangerZone } from 'expo';
const { GestureHandler } = DangerZone;
const {
PanGestureHandler,
TapGestureHandler,
State,
} = GestureHandler;
const DRAG_TOSS = 0.05;
export type PropType = {
children: any,
friction?: number,
leftThreshold?: number,
rightThreshold?: number,
overshootLeft?: boolean,
overshootRight?: boolean,
onSwipeableLeftOpen?: Function,
onSwipeableRightOpen?: Function,
onSwipeableOpen?: Function,
onSwipeableClose?: Function,
renderLeftActions?: (
progressAnimatedValue: any,
dragAnimatedValue: any
) => any,
renderRightActions?: (
progressAnimatedValue: any,
dragAnimatedValue: any
) => any,
useNativeAnimations?: boolean,
};
export default class Swipeable extends Component {
…
rest identical to https://github.com/kmagiera/react-native-gesture-handler/blob/master/Swipeable.js