forked from software-mansion/react-native-gesture-handler
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Swipe handler (software-mansion#145)
* Add basic support for swipe/fling * Add project files * Bump gradle version Add number of Touches handling Remove useless code from iOS pack Add android Fling Gesture Handler * Update react-native 🎉 * Rethink max duration on Android * Naname prop to 'numberOfTouches' * Update RN 🎉 * Rename comment * Fix issues * Rethink directions on ios * Add android multi-directional fling handling * Remove useless code and style issue * Update gradle, add yarn.lock * Shadow useless YellowBox * Rename issue and remove ios Example iOS file changes revert * Update README.md * Update README.md
- Loading branch information
Showing
15 changed files
with
351 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React, { Component } from 'react'; | ||
import { Animated, Dimensions, StyleSheet, Text, View } from 'react-native'; | ||
import { | ||
FlingGestureHandler, | ||
Directions, | ||
State, | ||
} from 'react-native-gesture-handler'; | ||
|
||
import { USE_NATIVE_DRIVER } from '../config'; | ||
|
||
const windowWidth = Dimensions.get('window').width; | ||
const circleRadius = 30; | ||
|
||
class Fling extends Component { | ||
constructor(props) { | ||
super(props); | ||
this._touchX = new Animated.Value(windowWidth / 2 - circleRadius); | ||
this._translateX = Animated.add( | ||
this._touchX, | ||
new Animated.Value(-circleRadius) | ||
); | ||
this._translateY = new Animated.Value(0); | ||
} | ||
|
||
_onVerticalFlingHandlerStateChange = ({ nativeEvent }, offset) => { | ||
if (nativeEvent.oldState === State.ACTIVE) { | ||
Animated.spring(this._touchX, { | ||
toValue: this._touchX._value + offset, | ||
useNativeDriver: USE_NATIVE_DRIVER, | ||
}).start(); | ||
} | ||
}; | ||
|
||
_onHorizontalFlingHandlerStateChange = ({ nativeEvent }) => { | ||
if (nativeEvent.oldState === State.ACTIVE) { | ||
Animated.spring(this._translateY, { | ||
toValue: this._translateY._value + 10, | ||
useNativeDriver: USE_NATIVE_DRIVER, | ||
}).start(); | ||
} | ||
}; | ||
|
||
render() { | ||
return ( | ||
<FlingGestureHandler | ||
direction={Directions.UP} | ||
numberOfPointers={2} | ||
onHandlerStateChange={this._onHorizontalFlingHandlerStateChange}> | ||
<FlingGestureHandler | ||
direction={Directions.RIGHT | Directions.LEFT} | ||
onHandlerStateChange={ev => | ||
this._onVerticalFlingHandlerStateChange(ev, -10) | ||
}> | ||
<View style={styles.horizontalPan}> | ||
<Animated.View | ||
style={[ | ||
styles.circle, | ||
{ | ||
transform: [ | ||
{ | ||
translateX: this._translateX, | ||
}, | ||
{ | ||
translateY: this._translateY, | ||
}, | ||
], | ||
}, | ||
]} | ||
/> | ||
</View> | ||
</FlingGestureHandler> | ||
</FlingGestureHandler> | ||
); | ||
} | ||
} | ||
|
||
export default class Example extends Component { | ||
render() { | ||
return ( | ||
<View> | ||
<Fling /> | ||
<Text> | ||
Move up (with two fingers) or right/left (with one finger) and watch | ||
magic happens | ||
</Text> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
horizontalPan: { | ||
backgroundColor: '#f76f41', | ||
height: 300, | ||
justifyContent: 'center', | ||
marginVertical: 10, | ||
}, | ||
circle: { | ||
backgroundColor: '#42a5f5', | ||
borderRadius: circleRadius, | ||
height: circleRadius * 2, | ||
width: circleRadius * 2, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
android/lib/src/main/java/com/swmansion/gesturehandler/FlingGestureHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package com.swmansion.gesturehandler; | ||
|
||
import android.os.Handler; | ||
import android.view.MotionEvent; | ||
|
||
public class FlingGestureHandler extends GestureHandler<FlingGestureHandler> { | ||
private static final long DEFAULT_MAX_DURATION_MS = 800; | ||
private static final long DEFAULT_MIN_ACCEPTABLE_DELTA = 160; | ||
private static final int DEFAULT_DIRECTION = DIRECTION_RIGHT; | ||
private static final int DEFAULT_NUMBER_OF_TOUCHES_REQUIRED = 1; | ||
|
||
private long mMaxDurationMs = DEFAULT_MAX_DURATION_MS; | ||
private long mMinAcceptableDelta = DEFAULT_MIN_ACCEPTABLE_DELTA; | ||
private int mDirection = DEFAULT_DIRECTION; | ||
private int mNumberOfPointersRequired = DEFAULT_NUMBER_OF_TOUCHES_REQUIRED; | ||
private float mStartX, mStartY; | ||
|
||
private Handler mHandler; | ||
private int mMaxNumberOfPointersSimultaneously; | ||
|
||
private final Runnable mFailDelayed = new Runnable() { | ||
@Override | ||
public void run() { | ||
fail(); | ||
} | ||
}; | ||
|
||
public void setNumberOfPointersRequired(int numberOfPointersRequired) { | ||
mNumberOfPointersRequired = numberOfPointersRequired; | ||
} | ||
|
||
public void setDirection(int direction) { | ||
mDirection = direction; | ||
} | ||
|
||
private void startFling(MotionEvent event) { | ||
mStartX = event.getRawX(); | ||
mStartY = event.getRawY(); | ||
begin(); | ||
mMaxNumberOfPointersSimultaneously = 1; | ||
if (mHandler == null) { | ||
mHandler = new Handler(); | ||
} else { | ||
mHandler.removeCallbacksAndMessages(null); | ||
} | ||
mHandler.postDelayed(mFailDelayed, mMaxDurationMs); | ||
} | ||
|
||
private boolean tryEndFling(MotionEvent event) { | ||
if (mMaxNumberOfPointersSimultaneously == mNumberOfPointersRequired && | ||
(((mDirection & DIRECTION_RIGHT) != 0 && | ||
event.getRawX() - mStartX > mMinAcceptableDelta) || | ||
((mDirection & DIRECTION_LEFT) !=0 && | ||
mStartX - event.getRawX() > mMinAcceptableDelta) || | ||
((mDirection & DIRECTION_UP) !=0 && | ||
mStartY - event.getRawY() > mMinAcceptableDelta) || | ||
((mDirection & DIRECTION_DOWN) !=0 && | ||
event.getRawY() - mStartY > mMinAcceptableDelta))) { | ||
mHandler.removeCallbacksAndMessages(null); | ||
activate(); | ||
end(); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
private void endFling(MotionEvent event) { | ||
if (!tryEndFling(event)) { | ||
fail(); | ||
} | ||
|
||
} | ||
|
||
@Override | ||
protected void onHandle(MotionEvent event) { | ||
int state = getState(); | ||
|
||
if (state == STATE_UNDETERMINED) { | ||
startFling(event); | ||
} | ||
|
||
|
||
if (state == STATE_BEGAN) { | ||
tryEndFling(event); | ||
if (event.getPointerCount() > mMaxNumberOfPointersSimultaneously) { | ||
mMaxNumberOfPointersSimultaneously = event.getPointerCount(); | ||
} | ||
|
||
int action = event.getActionMasked(); | ||
if (action == MotionEvent.ACTION_UP) { | ||
endFling(event); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
protected void onCancel() { | ||
if (mHandler != null) { | ||
mHandler.removeCallbacksAndMessages(null); | ||
} | ||
} | ||
|
||
@Override | ||
protected void onReset() { | ||
if (mHandler != null) { | ||
mHandler.removeCallbacksAndMessages(null); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#import "RNGestureHandler.h" | ||
|
||
@interface RNFlingGestureHandler : RNGestureHandler | ||
@end |
Oops, something went wrong.