React Native 全栈开发实战班 - 用户界面之手势系统应用_react-native-gesture-handler
在移动应用中,手势交互 是提升用户体验的重要手段。通过手势,用户可以更直观、自然地与应用进行交互。React Native 提供了强大的手势处理系统,允许开发者轻松实现各种手势操作,如滑动、缩放、旋转等。本章节将详细介绍 React Native 中的手势系统,包括如何使用内置的 PanResponder
和 Gesture Responder System
,以及如何使用第三方库(如 react-native-gesture-handler
)实现更复杂的手势交互。
2.1 手势系统概述
在 React Native 中,手势系统主要由以下两个部分组成:
- Gesture Responder System(手势响应系统): 负责处理触摸事件,确定哪个组件应该响应手势。
- PanResponder: 基于 Gesture Responder System,提供更高级的手势处理功能,支持多点触控和手势识别。
React Native 还提供了第三方库 react-native-gesture-handler
,用于实现更复杂和高效的手势交互。
2.2 使用 PanResponder
PanResponder
是 React Native 提供的一个高级手势处理 API,基于 Gesture Responder System 构建。它可以处理多种手势事件,如 onMoveShouldSetPanResponder
, onPanResponderMove
, onPanResponderRelease
等。
2.2.1 基本用法
步骤:
-
创建 PanResponder:
使用
PanResponder.create
创建一个 PanResponder 对象,并定义手势处理函数。const panResponder = useRef( PanResponder.create({ onStartShouldSetPanResponder: (evt, gestureState) => true, onPanResponderMove: (evt, gestureState) => { // 处理手势移动 }, onPanResponderRelease: (evt, gestureState) => { // 处理手势释放 }, })).current;
-
绑定 PanResponder 到组件:
将 PanResponder 的事件处理器绑定到组件的
onStartShouldSetPanResponder
,onPanResponderMove
,onPanResponderRelease
等属性。<View {...panResponder.panHandlers} style={styles.box}> {/* 内容 */}</View>
示例:
// DraggableBox.jsimport React, { useRef } from \'react\';import { View, Text, StyleSheet, PanResponder, Animated } from \'react-native\';const DraggableBox = () => { const pan = useRef(new Animated.ValueXY()).current; const panResponder = useRef( PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove: Animated.event( [ null, { dx: pan.x, // 横轴移动距离 dy: pan.y, // 纵轴移动距离 }, ], { useNativeDriver: false } ), onPanResponderRelease: () => { Animated.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: false, }).start(); }, }) ).current; return ( <View style={styles.container}> <Animated.View {...panResponder.panHandlers} style={[ styles.box, { transform: [{ translateX: pan.x }, { translateY: pan.y }], }, ]} > <Text style={styles.text}>Drag Me!</Text> </Animated.View> </View> );};const styles = StyleSheet.create({ container: { flex: 1, justifyContent: \'center\', alignItems: \'center\', }, box: { width: 200, height: 200, backgroundColor: \'#f0f0f0\', justifyContent: \'center\', alignItems: \'center\', borderRadius: 10, }, text: { fontSize: 18, },});export default DraggableBox;
解释:
Animated.event
将手势移动事件绑定到pan
动画值。onPanResponderRelease
使用Animated.spring
实现回弹动画。
2.2.2 多点触控
PanResponder
支持多点触控,可以处理多个手指同时操作。
示例:
// MultiTouchBox.jsimport React, { useRef } from \'react\';import { View, Text, StyleSheet, PanResponder, Animated } from \'react-native\';const MultiTouchBox = () => { const scale = useRef(new Animated.Value(1)).current; const pan = useRef(new Animated.ValueXY()).current; const panResponder = useRef( PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove: Animated.event( [ null, { dx: pan.x, dy: pan.y, scale: scale, }, ], { useNativeDriver: false } ), onPanResponderRelease: () => { Animated.spring(scale, { toValue: 1, useNativeDriver: false, }).start(); Animated.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: false, }).start(); }, }) ).current; return ( <View style={styles.container}> <Animated.View {...panResponder.panHandlers} style={[ styles.box, { transform: [{ translateX: pan.x }, { translateY: pan.y }, { scale }], }, ]} > <Text style={styles.text}>Multi-Touch!</Text> </Animated.View> </View> );};const styles = StyleSheet.create({ container: { flex: 1, justifyContent: \'center\', alignItems: \'center\', }, box: { width: 200, height: 200, backgroundColor: \'#f0f0f0\', justifyContent: \'center\', alignItems: \'center\', borderRadius: 10, }, text: { fontSize: 18, },});export default MultiTouchBox;
解释:
- 通过
scale
动画值实现缩放效果。 - 支持多点触控,实现缩放和拖拽。
2.3 使用 react-native-gesture-handler
react-native-gesture-handler
是一个功能强大的手势处理库,支持更复杂的手势交互,如滑动、缩放、旋转等。
2.3.1 安装 react-native-gesture-handler
npm install react-native-gesture-handler
2.3.2 基本用法
示例:
// SwipeableCard.jsimport React from \'react\';import { View, Text, StyleSheet, Animated } from \'react-native\';import { PanGestureHandler, State } from \'react-native-gesture-handler\';const SwipeableCard = () => { const translateX = React.useRef(new Animated.Value(0)).current; const onGestureEvent = Animated.event( [{ nativeEvent: { translationX: translateX } }], { useNativeDriver: true } ); const onHandlerStateChange = (event) => { if (event.nativeEvent.state === State.END) { if (translateX._value > 100) { Animated.timing(translateX, { toValue: 300, duration: 300, useNativeDriver: true, }).start(); } else { Animated.timing(translateX, { toValue: 0, duration: 300, useNativeDriver: true, }).start(); } } }; return ( <View style={styles.container}> <PanGestureHandler onGestureEvent={onGestureEvent} onHandlerStateChange={onHandlerStateChange}> <Animated.View style={[styles.card, { transform: [{ translateX }] }]}> <Text style={styles.text}>Swipe Me!</Text> </Animated.View> </PanGestureHandler> </View> );};const styles = StyleSheet.create({ container: { flex: 1, justifyContent: \'center\', alignItems: \'center\', }, card: { width: 200, height: 200, backgroundColor: \'#f0f0f0\', justifyContent: \'center\', alignItems: \'center\', borderRadius: 10, }, text: { fontSize: 18, },});export default SwipeableCard;
解释:
PanGestureHandler
处理滑动手势。Animated.event
将手势事件绑定到translateX
动画值。- 根据滑动距离实现卡片滑动效果。
2.3.3 高级用法
react-native-gesture-handler
支持多种手势识别器,如 PinchGestureHandler
, RotationGestureHandler
, TapGestureHandler
等。
作者简介
前腾讯电子签的前端负责人,现 whentimes tech CTO,专注于前端技术的大咖一枚!一路走来,从小屏到大屏,从 Web 到移动,什么前端难题都见过。热衷于用技术打磨产品,带领团队把复杂的事情做到极简,体验做到极致。喜欢探索新技术,也爱分享一些实战经验,帮助大家少走弯路!
温馨提示:可搜老码小张公号联系导师