software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
6.12k stars 980 forks source link

PanGesture does not work on Android on 0.58.6 #516

Closed kaiwen-zhang-ck closed 5 years ago

kaiwen-zhang-ck commented 5 years ago

I tried copying the example, but on 0.58.6 does not work on Android. iOS is fine. To reproduce

my package.json

{
  "name": "PanAnyDirection",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.6.3",
    "react-native": "0.58.6",
    "react-native-gesture-handler": "^1.1.0",
    "react-native-reanimated": "^1.0.0-alpha.12"
  },
  "devDependencies": {
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "24.4.0",
    "jest": "24.4.0",
    "metro-react-native-babel-preset": "0.53.0",
    "react-test-renderer": "16.6.3"
  },
  "jest": {
    "preset": "react-native"
  }
}

how is how i called it, this is from pan scroll example

import React, { Component } from "react";
import { Animated, Dimensions, StyleSheet, Text, View } from "react-native";
import {
  PanGestureHandler,
  TapGestureHandler,
  ScrollView,
  State
} from "react-native-gesture-handler";
import { USE_NATIVE_DRIVER } from "./config";

const windowWidth = Dimensions.get("window").width;
const circleRadius = 30;

export class TapOrPan extends Component {
  constructor(props) {
    super(props);
    this._touchX = new Animated.Value(windowWidth / 2 - circleRadius);
    this._translateX = Animated.add(
      this._touchX,
      new Animated.Value(-circleRadius)
    );
    this._onPanGestureEvent = Animated.event(
      [
        {
          nativeEvent: {
            x: this._touchX
          }
        }
      ],
      { useNativeDriver: USE_NATIVE_DRIVER }
    );
  }

  _onTapHandlerStateChange = ({ nativeEvent }) => {
    if (nativeEvent.oldState === State.ACTIVE) {
      // Once tap happened we set the position of the circle under the tapped spot
      this._touchX.setValue(nativeEvent.x);
    }
  };

  render() {
    const { tapRef, panRef } = this.props;
    return (
      <TapGestureHandler
        ref={tapRef}
        waitFor={panRef}
        onHandlerStateChange={this._onTapHandlerStateChange}
        shouldCancelWhenOutside
      >
        <Animated.View style={styles.wrapper}>
          <PanGestureHandler
            ref={panRef}
            activeOffsetX={[-20, 20]}
            onGestureEvent={this._onPanGestureEvent}
            shouldCancelWhenOutside
          >
            <Animated.View style={styles.horizontalPan}>
              <Animated.View
                style={[
                  styles.circle,
                  {
                    transform: [
                      {
                        translateX: this._translateX
                      }
                    ]
                  }
                ]}
              />
            </Animated.View>
          </PanGestureHandler>
        </Animated.View>
      </TapGestureHandler>
    );
  }
}

export default class Example extends Component {
  render() {
    const tapRef = React.createRef();
    const panRef = React.createRef();
    return (
      <ScrollView waitFor={[tapRef, panRef]}>
        <TapOrPan tapRef={tapRef} panRef={panRef} />
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  horizontalPan: {
    backgroundColor: "#f48fb1",
    height: 150,
    justifyContent: "center",
    marginVertical: 10
  },
  circle: {
    backgroundColor: "#42a5f5",
    borderRadius: circleRadius,
    height: circleRadius * 2,
    width: circleRadius * 2
  },
  wrapper: {
    flex: 1
  }
});

View loads and no error, but circle will not move from panning. Any ideas?

mekanics commented 5 years ago

I can confirm. I'm having the same issue.

react-native: 0.58.6 react-native-gesture-handler: 1.0.17

mekanics commented 5 years ago

Ok, I just forgot the Android Setup https://kmagiera.github.io/react-native-gesture-handler/docs/getting-started.html#android

Now, it's working and I feel like an idiot ¯_(ツ)_/¯

kaiwen-zhang-ck commented 5 years ago

@mekanics This is great. Android must change the activity to the following in order to work.

package com.swmansion.gesturehandler.react.example;

import com.facebook.react.ReactActivity;
+ import com.facebook.react.ReactActivityDelegate;
+ import com.facebook.react.ReactRootView;
+ import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

public class MainActivity extends ReactActivity {

  @Override
  protected String getMainComponentName() {
    return "Example";
  }

+  @Override
+  protected ReactActivityDelegate createReactActivityDelegate() {
+    return new ReactActivityDelegate(this, getMainComponentName()) {
+      @Override
+      protected ReactRootView createRootView() {
+       return new RNGestureHandlerEnabledRootView(MainActivity.this);
+      }
+    };
+  }
}
DevangMstryls commented 4 years ago

Ok, I just forgot the Android Setup https://kmagiera.github.io/react-native-gesture-handler/docs/getting-started.html#android

Now, it's working and I feel like an idiot ¯(ツ)

Updated Link: https://docs.swmansion.com/react-native-gesture-handler/docs/#android