React Navigation: Swipe on drawer does not work in Android-ThrowExceptions

Exception or error:

I have been searching for a solution for a long time, but surprisingly, I think nobody has faced it yet. So I am posting it.

I have created a simple Drawer Navigator with React Navigation V3. I have added a Menu icon, and when I click it, the drawer appears as it should be. But, no hand gesture is working. Swiping from left to right don’t do anything. Even when the drawer is open, tapping on empty space doesn’t close the drawer.

Here is my code:

import {
    createStackNavigator,
    createSwitchNavigator,
    createAppContainer,
    createDrawerNavigator
} from 'react-navigation';
import Home from './screens/Home';
import LoginForm from './screens/LoginForm';
import Articles from './screens/Articles';

const AuthStack = createStackNavigator({
    LoginScreen: LoginForm
});

const AppStack = createDrawerNavigator({
    HomeScreen: Home,
    ArticlesScreen: Articles
});

const RootNavigator = createSwitchNavigator(
    {
        Auth: AuthStack,
        App: AppStack
    },
    {
        initialRouteName: 'Auth'
    }
);

export default createAppContainer(RootNavigator);
How to solve:

I have found the solution. React Navigation depends on the react-native-gesture-handler library. In the Installation section of React Navigation docs, it only says to create link by using the command react-native link. This is enough for iOS. But for Android, you have to edit the MainActivity.java file, so that the gesture handler library can work as expected:

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);
+      }
+    };
+  }
}

Refer to the documentation: https://kmagiera.github.io/react-native-gesture-handler/docs/getting-started.html

Actually, it’s nowhere stated in React Navigation documentation to modify any files, as it is specific to react-native-gesture-handler and not React Navigation. I am keeping the answer here so it may help others.

UPDATE: The latest docs of React Navigation addresses this issue

###

Seems to be fixed in versions above 0.61.0, but for older versions this worked for me.

In the index.js :

. . .
import {gestureHandlerRootHOC} from 'react-native-gesture-handler';
AppRegistry.registerComponent(appName, () => gestureHandlerRootHOC(App));
. . .

###

In the index.js of your project just use gestureHandlerRootHOC:

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler'

AppRegistry.registerComponent(appName, () => gestureHandlerRootHOC(App));

resource: https://github.com/react-navigation/drawer/issues/105#issuecomment-540667009

Update:

In React Navigation > 5.x

Just put react-native-gesture-handler at the beginning of root index.js

import 'react-native-gesture-handler';

###

React native docs updated this issue and you can find a section named Installing dependencies into a bare React Native project in the below link

https://reactnavigation.org/docs/en/getting-started.html#installation

Leave a Reply

Your email address will not be published. Required fields are marked *