简体   繁体   English

panResponder开始移动时,如何在父类中调用自定义函数?

[英]How do I call a custom function in a parent class when panResponder starts moving?

If I have an imported component called <Draggable /> in react-native, 如果我在react-native中有一个名为<Draggable />的导入组件,

How do I call a custom function in the parent component when onPanResponderGrant decides the gesture has started? onPanResponderGrant确定手势已开始时,如何在父组件中调用自定义函数?

You'll see I'm passing an id of 'A' and 'B' into <Draggable /> , and I'd like to be able to call them back out on touch, and display them in the infoBox at the bottom of the main View ? 您会看到我正在将id 'A''B'传递给<Draggable /> ,我希望能够通过触摸回叫它们,并将它们显示在底部的信息infoBox 。主要View

// App

import React, { Component } from 'react'; 
import { View, Text, } from 'react-native';
import styles from './cust/styles';
import Draggable from './cust/draggable';

export default class Viewport extends Component {
    constructor(props){
        super(props);
        this.state = {
            dID  : null,
        };
    }
    render(){
        return (
          <View style={styles.mainContainer}>
                <View style={styles.draggableContainer}>
                      <Text>Draggable Container</Text>
                      <Draggable id='A' />
                      <Draggable id='B' />
                </View>
                <View style={styles.infoBar}>{this.infoBarData()}</View>
          </View>
        );
    }
    infoBarData(){
        if (this.state.dID) {
            return(
                <Text>{this.state.dID}</Text>
            )

        }
    }
}

and

// Draggable

import React, { Component } from 'react'; 
import { Text, PanResponder, Animated, } from 'react-native';
import styles from './styles';

class Draggable extends Component {
    constructor(props) {
        super(props);
        this.state = {
            pan : new Animated.ValueXY(),
        };
        this.panResponder = PanResponder.create({
            onStartShouldSetPanResponder    : () => true,
            onPanResponderMove              : Animated.event([null,{
                dx  : this.state.pan.x,
                dy  : this.state.pan.y,
            }]),
            onPanResponderRelease           : () => {
              Animated.spring(this.state.pan,{toValue:{x:0, y:0}}).start();
            }
        });
    }
    render() {
        return (
            <Animated.View
                {...this.panResponder.panHandlers}
                style={[this.state.pan.getLayout(), styles.circleAlt, styles.position]}>
                <Text style={styles.textAlt}>Drag me!</Text>
                <Text style={styles.textNum}>{this.props.id}</Text>
            </Animated.View>
        )
    }
}
export default Draggable;

EDIT 编辑

I've added the following to the parent class 我已将以下内容添加到父类中

// Object
<Draggable 
  onPanResponderMove={this.onStopMove}
  onPanResponderRelease={this.onMove}
  id='A' />

// Methods
onMove = (dID) => {
  this.setState({ dID });
}

onStopMove = () => {
  this.setState({ dID: null });
}

And I added the following to the Draggable class. 并将以下内容添加到Draggable类中。

// Methods
_handleOnPanResponderMove(evt, gestureState) {
    Animated.event([null,{
        // These animate movement on the X/Y axis
        dx  : this.state.pan.x,
        dy  : this.state.pan.y,
    }]);
    this.props.onPanResponderRelease(this.props.id);
}

But when I move the animated event out of the PanResponder.create({}) 但是当我将动画事件移出PanResponder.create({})

by doing the following, it loses it's ability to be dragged. 通过执行以下操作,它失去了被拖动的能力。 I assume this is something to do with 我认为这与

PanResponder.create({
    ..., 
    onPanResponder : this._handleOnPanResponder.bind(this),
    ...,
})

Not being returned a value? 没有返回值?

EDIT 2 编辑2

I also tried to add the following, but again, didn't work. 我也尝试添加以下内容,但再次失败了。

PanResponder.create({
    ..., 
    onPanResponder : (evt ,gesture) => {
        Animated.event([null,{
            // These animate movement on the X/Y axis
            dx  : this.state.pan.x,
            dy  : this.state.pan.y,
    }]);
    this.props.onPanResponderRelease(this.props.id);
    }
    ...,
})

You need to pass a callback handler with Draggable component, like 您需要使用Draggable组件传递回调处理程序,例如

<Draggable id="A" gestureHandler={(data) => {
/*
  do whatever you want to do with the data, like store it into state
*/
}}

In your Draggable component, call this handler as per your requirement (when it is decided that gesture has started), like 在您的Draggable组件中,根据需要调用此处理程序(确定手势已开始),例如

if (this.props.gestureHandler instanceof Function) {
   this.props.gestureHandler.call(this, this.props.id);
}

Ok, 好,

So here is the code that works for anybody who may come across this question. 因此,这里的代码适用于可能遇到此问题的任何人。

// App
import React, { Component } from 'react'; 
import {
    View,
    Text,
} from 'react-native';
import styles from './cust/styles';
import Draggable from './cust/draggable';

export default class Viewport extends Component {
    constructor(props){
        super(props);
        this.state = {
            dID  : null,
        };
    }
    render(){
        return (
          <View style={styles.mainContainer}>
                <View style={styles.draggableContainer}>
                      <Text>Draggable Container</Text>
                      <Draggable 
                        onPanResponderGrant={this.onMove}
                        onPanResponderRelease={this.onStopMove}
                        id='A' />
                      <Draggable
                        onPanResponderGrant={this.onMove}
                        onPanResponderRelease={this.onStopMove}
                        id='B' />
                </View>
                <View style={styles.infoBar}>{this.printInfo()}</View>
          </View>
        );
    }
    onMove = (dID) => {
      this.setState({ dID });
    }

    onStopMove = () => {
      this.setState({ dID: null });
    }
    printInfo(){
      if (this.state.dID) {  
        return(
          <Text>{this.state.dID}</Text>
        );
      }
    }
}


// Draggable
import React, { Component } from 'react'; 
import {
    Text,
    PanResponder,
    Animated,
} from 'react-native';
import styles from './styles';

class Draggable extends Component {
    constructor(props) {
        super(props);
        this.state = {
            pan                 : new Animated.ValueXY(),
        };
    this.panResponder = PanResponder.create({
        onStartShouldSetPanResponder    : () => true,
        onPanResponderGrant : () => {
          this.props.onPanResponderGrant(this.props.id)
        },
        onPanResponderMove              : Animated.event([null,{
            dx  : this.state.pan.x,
            dy  : this.state.pan.y,
        }]),
        onPanResponderRelease           : () => {
                  Animated.spring(
                    this.state.pan,
                    {toValue:{x:0, y:0}}
                  ).start();
                  this.props.onPanResponderRelease();
              },
    });
    }
    render() {
        return (
            <Animated.View
                {...this.panResponder.panHandlers}
                style={[this.state.pan.getLayout(), styles.circleAlt, styles.position]}>
                <Text style={styles.textAlt}>Drag me!</Text>
                <Text style={styles.textNum}>{this.props.id}</Text>
            </Animated.View>
        )
    }
}
export default Draggable;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM