如何在React Native中实现手指拖拽触发Pressable按钮功能?
React Native实现Pressable拖拽触摸触发功能
当前代码里的Pressable仅在手指首次按下时触发onPressIn,按住第一个按钮拖拽到其他按钮上时,后续按钮不会响应——因为初始触摸事件已被第一个Pressable捕获。要实现拖拽经过时触发按钮状态更新,需要通过父容器跟踪触摸位置,手动判断触摸点落在哪个按钮区域。
修改后的实现代码
import React, { useState, useRef } from "react"; import { View, Text, Pressable } from "react-native"; function Buttons() { const [touched, setTouched] = useState(null); // 存储每个按钮的ref,用于获取布局位置 const buttonRefs = { a: useRef(null), b: useRef(null), c: useRef(null), }; // 判断触摸点是否在指定按钮范围内 const isPointInButton = (point, buttonRef) => { if (!buttonRef.current) return false; let isInside = false; buttonRef.current.measureInWindow((x, y, width, height) => { const { pageX, pageY } = point; // 检查触摸点是否在按钮的坐标范围内 isInside = pageX >= x && pageX <= x + width && pageY >= y && pageY <= y + height; }); return isInside; }; // 处理触摸开始 const handleTouchStart = (e) => { const touchPoint = e.nativeEvent.pageX ? e.nativeEvent : e.nativeEvent.changedTouches[0]; Object.entries(buttonRefs).forEach(([key, ref]) => { if (isPointInButton(touchPoint, ref)) { setTouched(key); } }); }; // 处理触摸移动 const handleTouchMove = (e) => { const touchPoint = e.nativeEvent.pageX ? e.nativeEvent : e.nativeEvent.changedTouches[0]; let currentTouched = null; Object.entries(buttonRefs).forEach(([key, ref]) => { if (isPointInButton(touchPoint, ref)) { currentTouched = key; } }); setTouched(currentTouched); }; // 处理触摸结束 const handleTouchEnd = () => { setTouched(null); }; return ( <View style={{ flex: 1 }} onTouchStart={handleTouchStart} onTouchMove={handleTouchMove} onTouchEnd={handleTouchEnd} onTouchCancel={handleTouchEnd} // 处理触摸被中断的情况 > <Pressable ref={buttonRefs.a} style={{ flex: 1, margin: 32, backgroundColor: touched === "a" ? "blue" : "red" }} > <Text style={{ fontSize: 100 }}>a</Text> </Pressable> <Pressable ref={buttonRefs.b} style={{ flex: 1, margin: 32, backgroundColor: touched === "b" ? "blue" : "red" }} > <Text style={{ fontSize: 100 }}>b</Text> </Pressable> <Pressable ref={buttonRefs.c} style={{ flex: 1, margin: 32, backgroundColor: touched === "c" ? "blue" : "red" }} > <Text style={{ fontSize: 100 }}>c</Text> </Pressable> </View> ); } export default Buttons;
关键逻辑说明
- 按钮Ref与布局检测:通过
useRef获取每个Pressable实例,用measureInWindow方法获取按钮在屏幕上的坐标范围,判断触摸点是否落在按钮区域内。 - 触摸事件跟踪:父容器监听
onTouchStart、onTouchMove、onTouchEnd事件,实时更新当前触摸的按钮状态。 - 兼容触摸事件格式:处理原生触摸事件的不同格式(单点触摸时取
changedTouches数组第一个元素),确保在不同设备上正常工作。
内容的提问来源于stack exchange,提问作者Blogger Klik
相关产品推荐
相关产品推荐

