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, thisIDIt will always work.
  • moveX– The abscissa of the screen when the last movement was made
  • moveY– The screen ordinate of the last movement
  • x0– Screen coordinates when the responder is generated
  • y0– Screen coordinates when the responder is generated
  • dx– Cumulative lateral distance from the start of touch operation
  • dy– Cumulative longitudinal distance from the start of touch operation
  • vx– Current lateral movement speed
  • vy– Current longitudinal movement speed
  • numberActiveTouches– 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 right
  • gestureState.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 🙏🙏.