Saltar al contenido

React Native: presione dos veces hacia atrás para salir de la aplicación

Posterior a de una prolongada recopilación de información hemos podido resolver esta dificultad que suelen tener ciertos de nuestros usuarios. Te dejamos la respuesta y nuestro objetivo es que te resulte de gran ayuda.

Solución:

import React, Component from 'react';
import BackHandler, View, Dimensions, Animated, TouchableOpacity, Text from 'react-native';

let width, height = Dimensions.get('window');


export default class App extends Component 

    state = 
        backClickCount: 0
    ;

    constructor(props) 
        super(props);

        this.springValue = new Animated.Value(100) ;

    

    componentWillMount() 
        BackHandler.addEventListener('hardwareBackPress', this.handleBackButton.bind(this));
    

    componentWillUnmount() 
        BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton.bind(this));
    

    _spring() 
        this.setState(backClickCount: 1, () => 
            Animated.sequence([
                Animated.spring(
                    this.springValue,
                    
                        toValue: -.15 * height,
                        friction: 5,
                        duration: 300,
                        useNativeDriver: true,
                    
                ),
                Animated.timing(
                    this.springValue,
                    
                        toValue: 100,
                        duration: 300,
                        useNativeDriver: true,
                    
                ),

            ]).start(() => 
                this.setState(backClickCount: 0);
            );
        );

    


    handleBackButton = () => 
        this.state.backClickCount == 1 ? BackHandler.exitApp() : this._spring();

        return true;
    ;


    render() 

        return (
            
                
                    container box
                

                press back again to exit the app

                     BackHandler.exitApp()
                    >
                        Exit
                    

                
            
        );
    



const styles = 
    container: 
        flex: 1,
        justifyContent: "center",
        alignItems: "center"
    ,
    animatedView: 
        width,
        backgroundColor: "#0a5386",
        elevation: 2,
        position: "absolute",
        bottom: 0,
        padding: 10,
        justifyContent: "center",
        alignItems: "center",
        flexDirection: "row",
    ,
    exitTitleText: 
        textAlign: "center",
        color: "#ffffff",
        marginRight: 10,
    ,
    exitText: 
        color: "#e5933a",
        paddingHorizontal: 10,
        paddingVertical: 3
    
;

Ejecutar en snack.expo: https://snack.expo.io/HyhD657d7

Lo resolví de esta manera como Componente funcional separado. De esta manera, no es necesario que vuelva a codificarlo para cada aplicación, solo incluya el componente en su nueva aplicación y ¡ya está!

import * as React from 'react';
import useEffect, useState from 'react';
import Platform, BackHandler, ToastAndroid from 'react-native';

export const ExecuteOnlyOnAndroid = (props) => 
  const message = props;
  const [exitApp, setExitApp] = useState(0);
  const backAction = () => 
    setTimeout(() => 
      setExitApp(0);
    , 2000); // 2 seconds to tap second-time

    if (exitApp === 0) 
      setExitApp(exitApp + 1);

      ToastAndroid.show(message, ToastAndroid.SHORT);
     else if (exitApp === 1) 
      BackHandler.exitApp();
    
    return true;
  ;
  useEffect(() => 
    const backHandler = BackHandler.addEventListener(
      'hardwareBackPress',
      backAction,
    );
    return () => backHandler.remove();
  );
  return <>;
;

export default function DoubleTapToClose(props) 
  const message = 'tap back again to exit the App' = props;
  return Platform.OS !== 'ios' ? (
    
  ) : (
    <>
  );


=> Lo único que necesita es incluir este componente en su aplicación. <=

Debido a que IOS no tiene un botón de retroceso, IOS no necesita esta funcionalidad. El componente anterior detecta automáticamente si el dispositivo es Android o no.

De forma predeterminada, el mensaje que se muestra en Toast está predefinido en inglés, pero puede configurar uno propio si agrega una propiedad llamada message a su DoubleTapToClose-Component.

...
import DoubleTapToClose from '../lib/android_doubleTapToClose'; 
...
return(
    <>
        
        ...other Stuff goes here
    

Dependiendo de su estructura de navegación, debe verificar si se encuentra en una pantalla inicial de su aplicación o no. En mi caso, tengo un Cajón con múltiples StackNavigatiors en su interior. Entonces verifico si la pantalla actual es una pantalla inicial (índice: 0), o no. Si es así, configuro una variable de gancho que solo se usará para esas pantallas iniciales.

Se ve como esto:

const isCurrentScreenInitialOne = (state) => 
  const route = state.routes[state.index];
  if (route.state) 
    // Dive into nested navigators
    return isCurrentScreenInitialOne(route.state);
  
  return state.index === 0;
;

...
...

export default function App() {
...
  const [isInitialScreen, setIsInitialScreen] = useState(true);

  isInitialScreen && ()

...
...
 
            setIsInitialScreen(isCurrentScreenInitialOne(state));
          >

Si esa descripción te ayuda, no te pierdas de votar.

Un mejor enfoque sería simplemente usar BackHandler y ToastAndroid

import  BackHandler, ToastAndroid  from 'react-native';
//rest of imports

class SomeClass extends Component
    constructor(state, props) 
        super(state, props)
        this.state = 
            validCloseWindow: false
        
    
    async componentDidMount() 
        BackHandler.addEventListener('hardwareBackPress', this.handleBackButton.bind(this));
    

    componentWillUnmount() 
        BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton.bind(this));
    
    handleBackButton = () => 
        if (!this.props.navigation.canGoBack()) 
            if (this.state.validCloseWindow)
                return false;
            this.state.validCloseWindow = true
            setTimeout(() => 
                this.state.validCloseWindow = false
            , 3000);
            ToastAndroid.show("Press Again To Exit !", ToastAndroid.SHORT);
            return true;
        
    ;
//rest of component code

Solo asegúrese de usarlo en la página de ruta inicial para su navegación.

Si posees alguna desconfianza o capacidad de ascender nuestro crónica eres capaz de dejar una crítica y con deseo lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *