为什么我不能在React Native的Animated.event()中得到一个nativeEvent回调来启动?

问题描述 投票:0回答:1

为什么在React Native的 nativeEvent 回调在我的 Animated.event 的回调?

我的最终目标是实现防止可拖动的手势控制组件离开屏幕的逻辑,但在我弄清楚为什么所需的回调从未启动之前,我无法做到这一点。

我设置了一个 onGestureEvent 回调 <PanGestureHandler /> 组件,我给它传递了一个 Animated.event() 呼叫 nativeEvent 的回调 (参见他们的文档,了解如何做到这一点。).

我知道nativeEvent回调没有被触发,因为debug和console.log在 Animated.block() 没有输出任何东西到控制台(我使用Expo--------)。调试链接在此). 此外,还 set(_translateX, translationX) 一行 Animate.block() 调用也从来没有执行过,否则我希望看到箱子在拖动时移动(而不是当触摸被释放时)。

请注意,如果您取消下面的代码块,并删除了 { nativeEvent: function... } 后的对象,动画就能正常工作。

    {
      nativeEvent: {translationX: _translateX}
    },

我觉得我好像漏掉了一些很简单的东西 但我不知道是什么。

这里有一个expo世博会的链接,供大家调试。https:/snack.expo.iod8xCeHhtj。

这是我的代码。

import React, { Component } from 'react';
import {
  Dimensions,
  StyleSheet,
  Text,
  View,
  Button,
  Animated
} from 'react-native';
import {
  PanGestureHandler,
  ScrollView,
  State,
} from 'react-native-gesture-handler';
const {
  and,
  block,
  clockRunning,
  set,
  Clock,
  cond,
  eq,
  debug,
  Extrapolate,
  max,
  lessThan,
  greaterOrEq,
  Value,
  startClock,
  timing,
  call,
  stopClock,
} = Animated;

function Slider({color, width, height}) {
  const screenWidth = Dimensions.get('window').width;
  const _translateX = new Animated.Value(0);
  const _lastOffset = {x: 0};

  const cmpStyles = StyleSheet.create({
    box: {
      width: width,
      height: height,
      alignSelf: 'center',
      backgroundColor: color,
      margin: 30,
      zIndex: 200,
      color: color,
      transform: [
        {translateX: _translateX},
      ],
    },
  });

  const _onGestureEvent = Animated.event(
        [
  // Uncomment this block to see the original animation
    /*
            {
                nativeEvent: {translationX: _translateX}
            },
    */
  // Comment the following object when uncommenting the previous section
            {
                nativeEvent: function({ translationX, absoluteX }) {
                    return block([
                        debug('x', translationX),
                        call([], () => console.log('the code block was executed')),
                        set(_translateX, translationX),
                    ])
                }
            },
  // ------------------------------
        ],
        {
            useNativeDriver: true,
            listener: (event, gestureState) => {
                const {absoluteX, translationX} = event.nativeEvent;
                //console.log('translationX' + translationX);
                //console.log('dest' + _translateX._value);
            }
        }
  );
  const _onHandlerStateChange = event => {
    const {
      oldState,
      translationX,
      absoluteX,
    } = event.nativeEvent;
    if (oldState === State.ACTIVE) {
      //if (absoluteX + translationX > screenWidth) {
      //console.log("translationX: " + translationX);
      //console.log("screenWidth" + screenWidth);

      // Set the slider to correct position when gesture is released
      _lastOffset.x += translationX;
      _translateX.setOffset(_lastOffset.x);
      _translateX.setValue(0);
    }
  };

  return (
    <PanGestureHandler
      onGestureEvent={_onGestureEvent}
      onHandlerStateChange={_onHandlerStateChange}
            >
      <Animated.View style={cmpStyles.box} />
    </PanGestureHandler>
  );
}

export default function Example() {
  const width = 60;
  const height = 60;

  return (
    <View style={styles.scrollView}>
      <Slider color={'red'} width={width} height={height} />
      <Slider color={'blue'} width={width} height={height} />
      <Slider color={'green'} width={width} height={height} />
      <Slider color={'orange'} width={width} height={height} />
    </View>
  );
}

const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
    marginTop: 120,
  },
})

谢谢你的帮助。

reactjs react-native animation react-native-android react-native-gesture-handler
1个回答
1
投票

你可以使用 动画反应-原生-复活.

因为当我们导入nativeEvent时,nativeEvent调用不工作。动画原生

import React, { Component } from "react";
import { Dimensions, StyleSheet, Text, View, Button } from "react-native";
import { PanGestureHandler, State } from "react-native-gesture-handler";
import Animated from "react-native-reanimated";

const {
  and,
  block,
  clockRunning,
  set,
  Clock,
  cond,
  eq,
  debug,
  Extrapolate,
  max,
  lessThan,
  greaterOrEq,
  Value,
  startClock,
  timing,
  call,
  stopClock,
  event,
} = Animated;

function Slider({ color, width, height }) {
  const screenWidth = Dimensions.get("window").width;
  const _translateX = new Value(0);
  const _lastOffset = { x: 0 };

  const cmpStyles = StyleSheet.create({
    box: {
      width: width,
      height: height,
      alignSelf: "center",
      backgroundColor: color,
      margin: 30,
      zIndex: 200,
      color: color,
      transform: [{ translateX: _translateX }],
    },
  });
  const _onGestureEvent = event(
    [
      // Uncomment this block to see the original animation
      /*
            {
                nativeEvent: {translationX: _translateX}
            },
    */
      // Comment the following object when uncommenting the previous section
      {
        nativeEvent: ({ translationX: x, translationY: y, state }) =>
          block([
            // debug('x', _translateX),
            call([], () => console.log("the code block was executed")),
            set(_translateX, x),
          ]),
      },
    ],
    // ------------------------------
    {
        useNativeDriver: true,
        listener: (event, gestureState) => {
            const {absoluteX, translationX} = event.nativeEvent;
            //console.log('translationX' + translationX);
            //console.log('dest' + _translateX._value);
        }
    }
  );
  const _onHandlerStateChange = (event) => {
    const { oldState, translationX, absoluteX } = event.nativeEvent;
    if (oldState === State.ACTIVE) {
      //if (absoluteX + translationX > screenWidth) {
      //console.log("translationX: " + translationX);
      //console.log("screenWidth" + screenWidth);

      // Set the slider to correct position when gesture is released
      _lastOffset.x += translationX;
      _translateX.setValue(_lastOffset.x);
    }
  };

  return (
    <PanGestureHandler
      onGestureEvent={_onGestureEvent}
      onHandlerStateChange={_onHandlerStateChange}
    >
      <Animated.View style={cmpStyles.box} />
    </PanGestureHandler>
  );
}

export default function Example() {
  const width = 60;
  const height = 60;

  return (
    <View style={styles.scrollView}>
      <Slider color={"red"} width={width} height={height} />
      <Slider color={"blue"} width={width} height={height} />
      <Slider color={"green"} width={width} height={height} />
      <Slider color={"orange"} width={width} height={height} />
    </View>
  );
}

const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
    marginTop: 120,
  },
});


-1
投票

编写处理函数,如

handleSctoll = (e) => {
   console.log(e.nativeEvent.contentOffset.y);
}

你可以像这样添加监听器

Animated.event(
   [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
   { listener: (event) => this.handleSctoll(event) }
)
© www.soinside.com 2019 - 2024. All rights reserved.