This is the 27th day of my participation in the August Genwen Challenge.More challenges in August
preface
“The colors of August are made of gold, bright and precious; The colors of August are brewed with the sun, fragrant and brilliant.”
In the future, I wish you to adjust yourself to the best state, slowly work hard, slowly become better
This article follows from my previous article, Animated.
Today we used Animated to implement a simple shopping cart swipe-delete feature (modeled after Taobao).
Everything covered in this article uses functional components
Let’s start with the renderings
Understand PanResponder
React Native makes it easy to tap events (touches), but swiping to delete involves touching gestures. React Native itself also comes with an API for gesture developers to think about — PanResponder.
The PanResponder class can coordinate multi-touch actions into a gesture. It allows a single touch to accept more touches, and can also be used to recognize simple multi-touch gestures.
It provides a predictable wrapper around the touch response system responder. For each handler, it provides a new gestureState object in addition to the native event:
onPanResponderMove: (event, gestureState) => {}
Copy the code
A gestureState object has the following fields:
stateID
– Touch stateID
. In the case of at least one touch point on the screen, thisID
It will always work.moveX
– The abscissa of the screen when the last movement was mademoveY
– The screen ordinate of the last movementx0
– Screen coordinates when the responder is generatedy0
– Screen coordinates when the responder is generateddx
– Cumulative lateral distance from the start of touch operationdy
– Cumulative longitudinal distance from the start of touch operationvx
– Current lateral movement speedvy
– Current longitudinal movement speednumberActiveTouches
– The number of valid touch points currently on the screen
Create the PanResponder object
First we need to create a PanResponder object and set it as a responder
PanResponder. Create ({/ / respond to touch events, if returns false, the invalid onStartShouldSetPanResponder: () = > true, onMoveShouldSetPanResponder: () => true, })Copy the code
Setting Animated
In the last article, we looked at how Animated is used. I won’t repeat it here
Initializes the value that creates the driver animation
const pan = useRef(new Animated.Value(0)).current;
Copy the code
Execute the animation, using the Animated.spring() elastic model.
/** * @description: * @param {number} num */ const _startAnimated = num => {Animated. Spring (pan, {toValue: Num, // Set the animation's attribute value useNativeDriver: true,}).start(); };Copy the code
The touch event performs the animation
When sliding, we get its gesturestate. dx, and determine the sliding direction by judging the positive and negative values of gesturestate. dx.
gestureState.dx
> 0 swipe rightgestureState.dx
< 0 swipe left
Transform: [{translateX: pan}],
OnPanResponderMove: (event, gestureState) => {console.log('move: ', gesturestate.dx); // Swipe right if (gesturestate. dx > 0) {_startAnimated(0); } else if(gesturestate. dx <= -50) {// Slide left _startAnimated(-150); }}Copy the code
The complete code
import React, {useRef, useState, useCallback} from 'react'; import { Animated, View, StyleSheet, PanResponder, Text, TouchableOpacity, Alert, } from 'react-native'; const WIDTH = 50; const SwipeAction = () => { const [contentWidth, setContentWidth] = useState(0); const pan = useRef(new Animated.Value(0)).current; const panResponder = useRef( PanResponder.create({ onStartShouldSetPanResponder: (evt, gestureState) => true, onMoveShouldSetPanResponder: () => true, onPanResponderGrant: (evT, gestureState) => {// Start gesture operation. Give the user some visual feedback so they know what's going on! console.log('start'); }, onPanResponderMove: (event, gestureState) => { console.log('move: ', gestureState.dx); // Swipe right if (gesturestate. dx > 0) {_startAnimated(0); } else if(gesturestate. dx <= -width) {// slide left _startAnimated(-width * 3); } }, // onPanResponderRelease: (evt, gestureState) => { // }, }), ).current; Const onLayout = ({nativeEvent: {layout: {width},},}) => {setContentWidth(width); }; /** * @description: * @param {number} num */ const _startAnimated = num => {Animated. Spring (pan, {toValue: num, useNativeDriver: true, }).start(); }; Const handleDelete = () => {Alert. Alert ('Alert Title', 'sure to delete? ', [ { text: 'Cancel', onPress: () => _startAnimated(0), style: 'cancel', }, { text: 'OK', onPress: () => _startAnimated(0), }, ]); }; return ( <View style={styles.container} onLayout={onLayout}> <TouchableOpacity> <Text style={[styles.text, Styles.search]}> find similar </Text> </TouchableOpacity> <TouchableOpacity> <View style={styles.insertcollect}> <Text Style ={styles.text}> move to </ text > < text style={styles.text}> favorites </ text > </View> </TouchableOpacity> <TouchableOpacity onPress={handleDelete}> <Text style={[styles.text, Styles.delete]}> Delete </Text> </TouchableOpacity> <Animated.View style={[styles.content, {width: contentWidth, transform: [{translateX: pan}], }, ]} {... PanHandlers}> <View> <Text style={styles.box}> This is a description </Text> </View> </Animated.View> </View> ); }; const styles = StyleSheet.create({ container: { flexDirection: 'row', marginTop: 100, backgroundColor: '#FFF', justifyContent: 'flex-end', }, titleText: { fontSize: 14, lineHeight: 24, fontWeight: 'bold', }, content: { position: 'absolute', backgroundColor: '#fff', }, box: { height: 80, lineHeight: 80, borderRadius: 0, textAlign: 'center', color: 'black', }, delete: { backgroundColor: '#DF3409', height: 80, lineHeight: 80, width: WIDTH, textAlign: 'center', }, insertCollect: { backgroundColor: '#FF6347', height: 80, lineHeight: 80, width: WIDTH, justifyContent: 'center', alignItems: 'center', }, search: { backgroundColor: '#FFBA30', height: 80, lineHeight: 80, width: WIDTH, textAlign: 'center', }, text: { color: '#fff', }, }); export default SwipeAction;Copy the code
conclusion
So that’s a simple swipe delete animation.
If this article helped you, please like 👍 and follow ⭐️.
If there are any errors in this article, please correct them in the comments section 🙏🙏.