Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
React native React本机pan应答器设置边界,有时不工作_React Native - Fatal编程技术网

React native React本机pan应答器设置边界,有时不工作

React native React本机pan应答器设置边界,有时不工作,react-native,React Native,我正在尝试使用react nativePanResponder 在用户平移时,我使用动画.ValueXY值更新动画.View,当用户点击左边框或右边框时,我想停止移动此动画.View我以某种方式管理了它,但当用户滑动更快时,该视图不会在边框上停止,并且超出了限制 我怎样才能解决这个问题 这是完整的代码 import React, { useRef, useEffect } from 'react' import { Platform, View, PanResponder

我正在尝试使用react native
PanResponder
在用户平移时,我使用
动画.ValueXY
值更新
动画.View
,当用户点击左边框或右边框时,我想停止移动此
动画.View
我以某种方式管理了它,但当用户滑动更快时,该视图不会在边框上停止,并且超出了限制

我怎样才能解决这个问题

这是完整的代码

import React, { useRef, useEffect } from 'react'
import {
    Platform,
    View,
    PanResponder,
    Animated,
  Dimensions,
  StyleSheet
} from 'react-native';
import PropTypes from 'prop-types';

function usePanResponders({ parentWidth, reverse, width, values, onMoving}) {
    const endXPos = parentWidth - width;
    const _values = useRef({...values}).current;
    const pan = useRef(new Animated.ValueXY({...values})).current

    useEffect(() => {
        pan.addListener((values) => {
            _values.x = values.x
        });
        return () => {
            pan.removeAllListeners();
        }
    }, [])

    return [useRef(PanResponder.create({
        onMoveShouldSetPanResponder: () => true,
        onMoveShouldSetPanResponderCapture: (_, { dx }) => Math.abs(dx) > 20,
        onPanResponderGrant: () => {
            if(!reverse) {
                console.log(reverse)
                pan.setOffset({x: _values.x, y: _values.y});
                pan.setValue({x: 0, y: 0});
            }
        },
        onPanResponderMove: (e, gestureState) => {
            const isMovingLeft = gestureState.dx > 0;
            // this is how i stops right border
            if((_values.x >= endXPos) && isMovingLeft) return null;
            // left border
            if(!isMovingLeft && _values.x <= 0) return null;

            return Animated.event(
                [ null,
                {dx: pan.x}
                ], 
                {listener: null}
            )(e, gestureState);
        },
        onPanResponderRelease: () => onMoving(_values)
    })).current, pan];
}

function useCss({width, height, color}) {
   return [
    Platform.select({
        ios: {
            zIndex: 999,
            position: 'absolute',
        },
        android: {
            position: 'absolute',
        }
    }),
    {
        backgroundColor: color,
        width,
        height
    }
   ]
}

function AsyncDraggable({x, y, width, height, color, parentWidth, reverse, onDragEnd}) {
    const [position, item] = useCss({width, height, color})
    const onMoving = (v) => {
        console.log(v)
    }
    const values = {x, y}
    console.log('Rendering...')
    const [panresponder, pan] = usePanResponders({parentWidth, reverse, width, pan, values, onMoving})
    return (
        <View style={{...position}}>
                <Animated.View
                    {...panresponder.panHandlers}
                    style={[pan.getLayout()]}>
                    <View
                        style={{...item}}
                    >       
                    </View>
                </Animated.View>
            </View>
    )
}

AsyncDraggable.prototype = {
    width: PropTypes.number,
    height: PropTypes.number,
    color: PropTypes.string,
    parentWidth:PropTypes.number.isRequired,
    onDragEnd: PropTypes.func,
    onMove: PropTypes.func,
      x:PropTypes.number,
      y:PropTypes.number
}

AsyncDraggable.defaultProps = {
    x : 0,
    y : 0,
    reverse : false,
    onMove: () => {}
}

const margin = {
    top: 10,
    bottom: 20,
    left: 50,
    right: 15
};

const screenWidth = Dimensions.get('window').width;

function Scroller({width, height,  panWidth}){
    const computedWidth = width - (margin.left + margin.right);
    const _height = height || 70

    return (
        <View style={{
            marginLeft: margin.left,
            marginRight: margin.right,
            marginTop: margin.top,
            width: computedWidth, 
            overflow: 'hidden',
            height, 
            backgroundColor: 'rgba(255,255,255,0.04)'}}>
            <AsyncDraggable x={10} color={'yellow'} parentWidth={computedWidth} width={panWidth} height={_height}/>
        </View>
    )
}

Scroller.prototype = {
    height: PropTypes.number,
    width: PropTypes.number,
}

Scroller.defaultProps = {
    height: 70,
    width: screenWidth,
    panWidth: 60
}

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Scroller/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    padding: 8
  }
});
import React,{useRef,useffect}来自“React”
进口{
平台,
看法
应答器,
有生气的
尺寸,
样式表
}从“反应本机”;
从“道具类型”导入道具类型;
函数usePanResponders({parentWidth,reverse,width,values,onMoving}){
const endXPos=parentWidth-width;
const_values=useRef({…values}).current;
const pan=useRef(新的动画.ValueXY({…values})).current
useffect(()=>{
pan.addListener((值)=>{
_values.x=values.x
});
return()=>{
pan.removeAllListeners();
}
}, [])
return[useRef(PanResponder.create({
onMoveShouldSetPanResponder:()=>true,
onMoveShouldSetPanResponderCapture:(u,{dx})=>Math.abs(dx)>20,
onPanResponderGrant:()=>{
如果(!反向){
console.log(反向)
setOffset({x:_values.x,y:_values.y});
集值({x:0,y:0});
}
},
onPanResponderMove:(e,手势状态)=>{
常数isMovingLeft=gestureState.dx>0;
//这就是我如何停止右边界
if((_values.x>=endXPos)和&isMovingLeft)返回null;
//左边框
如果(!isMovingLeft&&&u values.x onMoving(\u values)
})).当前,pan];
}
函数useCss({宽度、高度、颜色}){
返回[
Platform.select({
ios:{
zIndex:999,
位置:'绝对',
},
安卓:{
位置:'绝对',
}
}),
{
背景颜色:颜色,
宽度,
高度
}
]
}
函数AsyncDraggable({x,y,width,height,color,parentWidth,reverse,onDragEnd}){
const[position,item]=useCss({宽度,高度,颜色})
移动常数=(v)=>{
控制台日志(v)
}
常量值={x,y}
console.log('Rendering…'))
const[panresponder,pan]=usepanresponder({parentWidth,reverse,width,pan,values,onMoving})
返回(
)
}
AsyncDragTable.prototype={
宽度:PropTypes.number,
高度:PropTypes.number,
颜色:PropTypes.string,
parentWidth:PropTypes.number.isRequired,
onDragEnd:PropTypes.func,
onMove:PropTypes.func,
x:PropTypes.number,
y:PropTypes.number
}
AsyncDragTable.defaultProps={
x:0,,
y:0,
反面:错,
onMove:()=>{}
}
常量边距={
前10名,
底数:20,
左:50,,
右:15
};
const screenWidth=Dimensions.get('window').width;
函数滚动条({width,height,panWidth}){
const computedWidth=宽度-(margin.left+margin.right);
常数|高度=高度| 70
返回(
)
}
Scroller.prototype={
高度:PropTypes.number,
宽度:PropTypes.number,
}
Scroller.defaultProps={
身高:70,
宽度:屏幕宽度,
窗格宽度:60
}
导出默认类App扩展React.Component{
render(){
返回(
);
}
}
const styles=StyleSheet.create({
容器:{
填充:8
}
});
正如你在代码上看到的

if((_values.x >= endXPos) && isMovingLeft) return null;

if(!isMovingLeft && _values.x <= 0) return null;
if((_values.x>=endXPos)和&isMovingLeft)返回null;

如果(!isMovingLeft&&&_values.x,如果它超出边界,您可以做一件事,您可以在onPanResponderRelease回调上检查它,并将标记位置重置或更新到边界限制