react native 实现拖动view (完善边界处理)

大致思路:

  • 使用 PanResponder api实现拖拽 
  • 使用Dimensions 获取屏幕宽度 判断拖拽边界处理
import { Dimensions, View, Text, TouchableHighlight, PanResponder, Animated, StyleSheet } from 'react-native'

const ScreenWidth = Dimensions.get('window').width
const ScreenHeight = Dimensions.get('window').height
const onlineIconHeight = 40 // 盒子自身高度
const onlineIconWidth = 40 // 盒子自身宽度

class AppWithNavigationState extends React.Component {
    constructor (props) {
        super(props)
        this.state = {
            pan: new Animated.ValueXY(),
            panResponder: null,
            left: ScreenWidth - onlineIconWidth,
            bottom: 100
        }
    }

     componentDidMount () {
        this.onlineDrag()
    }

    onlineDrag = () => {
        this._panResponder = PanResponder.create({
            onStartShouldSetPanResponder: () => true,
            onMoveShouldSetResponderCapture: () => true,
            onMoveShouldSetPanResponderCapture: () => true,
            // 用户开始触摸点
            onPanResponderGrant: (e, gestureState) => {
                this.startX = this.state.left // 起始位置
                this.startY = this.state.bottom
            },
            // 用户开始移动
            onPanResponderMove: (e, g) => {
                let left = this.startX + g.dx // 距离左侧距离
                let bottom = this.startY - g.dy // 距离底部距离

                // 边界处理
                if (left <= 0) {
                    left = 0
                }
                if(left >= ScreenWidth - onlineIconWidth) {
                    left = ScreenWidth - onlineIconWidth
                }
                if(bottom <= 0) {
                    bottom = 0
                }
                if(bottom >= ScreenHeight - 100) {
                    bottom = ScreenHeight - 100
                }

                this.setState({
                    left: left,
                    bottom: bottom
                })
            },
            // 用户放开了所有的触摸点
            onPanResponderRelease: (e, g) => {
                this.startX = this.state.left
                this.startY = this.state.bottom
            }
        })
    }

  render () {
        return (
            <Animated.View
        style={{
            transform: [ { translateX: this.state.pan.x }, { translateY: this.state.pan.y } ], position: 'absolute', left: this.state.left, bottom: this.state.bottom, backgroundColor: 'rgb(179, 127, 235)', width: onlineIconWidth, height: onlineIconHeight, borderRadius: 30
        }}
        {...this._panResponder?.panHandlers }

    >
        <TouchableHighlight
            onPress={() => {
                // 自定义自己的点击事件逻辑
            }}
        >
            <Text>拖拽的盒子</Text>
        </TouchableHighlight>
    </Animated.View>
        )
    }
}

export default AppWithNavigationState;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值