import React, { Component } from 'react';
import { Animated, StyleSheet, Text, View } from 'react-native';
import {
PanGestureHandler,
ScrollView,
State,
RectButton,
BorderlessButton,
LongPressGestureHandler,
} from 'react-native-gesture-handler';
import { USE_NATIVE_DRIVER } from '../config';
import { LoremIpsum } from '../common';
const RATIO = 3;
export class Swipeable extends Component {
constructor(props) {
super(props);
this._width = 0;
this._dragX = new Animated.Value(0);
this._transX = this._dragX.interpolate({
inputRange: [0, RATIO],
outputRange: [0, 1],
});
this._showLeftAction = this._dragX.interpolate({
inputRange: [-1, 0, 1],
outputRange: [0, 0, 1],
});
this._showRightAction = this._dragX.interpolate({
inputRange: [-1, 0, 1],
outputRange: [1, 0, 0],
});
this._onGestureEvent = Animated.event(
[{ nativeEvent: { translationX: this._dragX } }],
{ useNativeDriver: USE_NATIVE_DRIVER }
);
}
_onHandlerStateChange = event => {
if (event.nativeEvent.oldState === State.ACTIVE) {
const dragToss = 0.05;
const endOffsetX =
event.nativeEvent.translationX + dragToss * event.nativeEvent.velocityX;
let toValue = 0;
if (endOffsetX > this._width / 2) {
toValue = this._width * RATIO;
} else if (endOffsetX < -this._width / 2) {
toValue = -this._width * RATIO;
}
Animated.spring(this._dragX, {
velocity: event.nativeEvent.velocityX,
tension: 15,
friction: 5,
toValue,
useNativeDriver: USE_NATIVE_DRIVER,
}).start();
}
};
_onLayout = event => {
this._width = event.nativeEvent.layout.width;
};
_reset = () => {
Animated.spring(this._dragX, {
toValue: 0,
useNativeDriver: USE_NATIVE_DRIVER,
tension: 15,
friction: 5,
}).start();
};
render() {
const { children } = this.props;
return (
Green
Red
{children}
);
}
}
export const InfoButton = props => (
alert(`${props.name} info button clicked`)}>
i
);
export default class Example extends Component {
render() {
return (
alert('First row clicked')}>
Swipe this row & observe highlight delay
{/* Info icon will cancel when you scroll in the direction of the scrollview
but if you move finger horizontally it would allow you to "re-enter" into
an active state. This is typical for most of the buttons on iOS (but not
on Android where the touch cancels as soon as you leave the area of the
button). */}
alert('Second row clicked')}>
Second info icon will block scrolling
{/* Info icon will block interaction with other gesture handlers including
the scrollview handler its a descendant of. This is typical for buttons
embedded in a scrollable content on iOS. */}
alert('Third row clicked')}>
This one will cancel when you drag outside
{/* Info icon will cancel when you drag your finger outside of its bounds and
then back unlike all the previous icons that would activate when you re-enter
their activation area. This is a typical bahaviour for android but less frequent
for most of the iOS native apps. */}
alert('Fourth row clicked')}>
This row is "disabled" but you can swipe it
nativeEvent.state === State.ACTIVE && alert('Long')
}>
alert('Fifth row clicked')}>
Clickable row with long press handler
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
rectButton: {
flex: 1,
height: 60,
padding: 10,
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
backgroundColor: 'white',
},
rowAction: {
...StyleSheet.absoluteFillObject,
justifyContent: 'center',
alignItems: 'center',
},
leftAction: {
backgroundColor: '#4CAF50',
},
rightAction: {
backgroundColor: '#F44336',
},
actionButtonText: {
color: 'white',
fontSize: 16,
},
buttonDelimiter: {
height: 1,
backgroundColor: '#999',
},
buttonText: {
fontWeight: 'bold',
backgroundColor: 'transparent',
},
infoButton: {
width: 40,
height: 40,
},
infoButtonBorders: {
borderColor: '#467AFB',
borderWidth: 2,
width: 20,
height: 20,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
margin: 10,
},
infoButtonText: {
color: '#467AFB',
fontWeight: 'bold',
backgroundColor: 'transparent',
},
});