Quantcast
Channel: Active questions tagged react-native+android - Stack Overflow
Viewing all articles
Browse latest Browse all 28468

React Native onPanResponderGrant is not called in Android but it works fine in iOS

$
0
0

I'm trying to implement drawer in react native using PanResponder and Animated.

I have the following code:

CustomDrawer.js

import React, { Component } from 'react';
import {
    View,
    Text,
    TouchableHighlight,
    Modal,
    TouchableWithoutFeedback,
    Animated,
    Dimensions,
    TouchableOpacity,
    PanResponder
}
from 'react-native';
import { setTimeout } from 'core-js/library/web/timers';

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height; 
const DRAWER_WIDTH = 300;
const SWIPE_THERSHOLD = DRAWER_WIDTH * 0.2;

class CustomDrawer extends Component {

    visible = false;
    starting = false;

    state = {
        drawerVisible: false,
    }


    constructor(props){
        super(props);
        const { drawerVisible } = this.state;        
        const panResponder = PanResponder.create({
            onStartShouldSetPanResponder: (evt, gestureState) => true,
            onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
            onMoveShouldSetPanResponder: (evt, gestureState) => true,
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
            onPanResponderMove: (event, gesture) => {
                if(this.visible){
                    if(gesture.dx<0){
                        this.position.setValue({ x: gesture.dx, y: 0});
                    }
                    else if(gesture.dx<DRAWER_WIDTH){
                        this.position.setValue({ x: -DRAWER_WIDTH + gesture.dx, y: 0});
                    }


                }
            },
            onPanResponderRelease: (event, gesture) => {                
                if(this.visible) {
                    if(gesture.dx> 10){
                        this.starting = false;                        
                    }
                    if(gesture.dx>0){
                        if(gesture.dx>=SWIPE_THERSHOLD){
                            this.forceDrawer('right');
                        }
                        else{
                            this.resetAnim();
                        }
                    }
                    else if(gesture.dx!=0) {
                        if(gesture.dx < - SWIPE_THERSHOLD){
                            this.setState({ drawerVisible: false});
                            this.forceDrawer('left');
                        }       
                        else {
                            this.renderAnim();
                        }
                    }

                }
                if(this.starting){
                    this.resetAnim();
                }
            },
            onPanResponderGrant: (event, gesture) => {
                console.log(gesture)

                setTimeout(()=> {
                    if(gesture.x0<10 && !gesture.x0==0){
                        console.log(gesture.x0);
                        this.setState({ drawerVisible: true})
                        this.visible=true;
                        this.starting = true;
                        this.position.setValue({ x: 10- DRAWER_WIDTH, y: 0})
                    }
                }, 500)
                return true;
            },

        });

        this.state = { drawerVisible: false, panResponder }
    }

    forceDrawer(direction) {
        const x = direction === 'right' ? 0 : -DRAWER_WIDTH;

        Animated.timing(this.position,{
            toValue: {x: x, y: 0},
            duration: 400
        }).start();
    }
    componentWillMount() {
        this.position = new Animated.ValueXY({x: -SCREEN_WIDTH, y: 0});
    }

    renderAnim(){
        Animated.timing(this.position, {
            toValue: { x: 0, y: 0},
            duration: 400
        }).start();
    }

    resetAnim() {
        this.starting = false;
        this.setState({ drawerVisible: false});
        this.visible = false;
        Animated.timing(this.position, {
            toValue: { x: -SCREEN_WIDTH, y: 0},
            duration: 250
        }).start();
    }

    renderBackground() {
        if(this.state.drawerVisible) {
            return(
                <TouchableOpacity style={styles.backgroundDrawer}
                    onPress={ () => {
                        this.resetAnim();
                        this.setState({drawerVisible: false});
                    }}>
                </TouchableOpacity>
            )
        }
    }

    render() {
        return(
            <View style={{flex: 1}}
            {...this.state.panResponder.panHandlers}>
                <View style={styles.viewStyle}>
                    <TouchableOpacity onPress={()=> {
                        this.renderAnim();
                        this.setState({ drawerVisible: true})
                        this.visible=true
                    }}>
                        <Text>Open Drawer</Text>
                    </TouchableOpacity>
                </View>

                {this.renderBackground()}

                <Animated.View style={[this.position.getLayout(),styles.drawerStyle]}  
                >
                    <Text>Contents</Text>
                </Animated.View>
            </View>
        )
    }
}


const styles = {
    viewStyle: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        overflow: 'hidden'
    },
    backgroundDrawer: {
        height: SCREEN_HEIGHT,
        width: SCREEN_WIDTH,
        backgroundColor: 'rgba(0,0,0,0.2)',
        position: 'absolute'
    },
    drawerStyle: {
        backgroundColor: 'white', 
        justifyContent: 'center',
        alignItems: 'center',        
        width: DRAWER_WIDTH,
        height: SCREEN_HEIGHT,
        position: 'absolute',
        elevation: 6,
        overflow: 'hidden'
    },

}
export default CustomDrawer;

As you can see here, i'm trying to move the drawer view, when the user presses on left corner for 500ms and the drawer view moves by 10pixels and user can drag it.

This works fine on iOS as you can see here

CustomDrawer

image

But the same is not working in Android. I tried debugging and onPanResponderGrant is not called in Android.


Viewing all articles
Browse latest Browse all 28468

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>