React Native 之 PanResponder(多点触摸)(十六)

在 React Native 中,PanResponder 是一个用于处理触摸手势的底层 API特别是用于处理平移(pan)手势(即用户在屏幕上拖动手指)。PanResponder 允许你捕获并响应一系列的触摸事件,如开始(start)、移动(move)、结束(end)和取消(cancel)。这使得开发者能够创建复杂的触摸交互,如拖拽、滑动等。

基本用法

const ExampleComponent = () => {
  const panResponder = React.useRef(
    PanResponder.create({
      // 要求成为响应者:
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onStartShouldSetPanResponderCapture: (evt, gestureState) =>
        true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) =>
        true,

      onPanResponderGrant: (evt, gestureState) => {
        // 开始手势操作。给用户一些视觉反馈,让他们知道发生了什么事情!
        // gestureState.d{x,y} 现在会被设置为0
      },
      onPanResponderMove: (evt, gestureState) => {
        // 最近一次的移动距离为gestureState.move{X,Y}
        // 从成为响应者开始时的累计手势移动距离为gestureState.d{x,y}
      },
      onPanResponderTerminationRequest: (evt, gestureState) =>
        true,
      onPanResponderRelease: (evt, gestureState) => {
        // 用户放开了所有的触摸点,且此时视图已经成为了响应者。
        // 一般来说这意味着一个手势操作已经成功完成。
      },
      onPanResponderTerminate: (evt, gestureState) => {
        // 另一个组件已经成为了新的响应者,所以当前手势将被取消。
      },
      onShouldBlockNativeResponder: (evt, gestureState) => {
        // 返回一个布尔值,决定当前组件是否应该阻止原生组件成为JS响应者
        // 默认返回true。目前暂时只支持android。
        return true;
      },
    }),
  ).current;

  return <View {...panResponder.panHandlers} />;
};

创建一个可以拖动的视图代码栗子:

import React, { useRef, useState } from 'react';  
import { View, Animated, PanResponder } from 'react-native';  
  
const DraggableView = () => {  
  const [position, setPosition] = useState({ x: 0, y: 0 });  
  const panResponder = useRef(  
    PanResponder.create({  
      onMoveShouldSetPanResponder: (_, { dx, dy, x, y }) => {  
        // 允许在水平或垂直方向上移动超过一定阈值(例如 5)时成为响应者  
        return Math.abs(dx) > 5 || Math.abs(dy) > 5;  
      },  
      onPanResponderGrant: (_, { x, y }) => {  
        // 当开始拖动时,记录初始位置  
        setPosition((prev) => ({ ...prev, moveX: x, moveY: y }));  
      },  
      onPanResponderMove: (_, { dx, dy }) => {  
        // 在拖动过程中更新位置  
        setPosition((prev) => ({ ...prev, x: prev.x + dx, y: prev.y + dy }));  
      },  
      onPanResponderRelease: (_, { x, y, vx, vy }) => {  
        // 当拖动结束时,可以执行一些清理或动画逻辑  
        // 这里只是简单地停止更新位置  
      },  
    })  
  ).current;  
  
  const animatedStyle = {  
    transform: [{ translateX: position.x }, { translateY: position.y }],  
  };  
  
  return (  
    <Animated.View  
      style={[styles.container, animatedStyle]}  
      {...panResponder.panHandlers}  
    >  
      {/* 视图内容 */}  
      <Text>Drag Me</Text>  
    </Animated.View>  
  );  
};  
  
const styles = {  
  container: {  
    width: 100,  
    height: 100,  
    backgroundColor: 'skyblue',  
    // 添加一些样式以确保视图可以拖动  
    marginTop: 50,  
    marginLeft: 50,  
  },  
};  
  
export default DraggableView;
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值