Кнопка Back Button React native exit

Я поместил кнопку обратной связи Android в функциональность приложения в своем собственном приложении для реагирования на моем домашнем экране. Но когда я нажимаю кнопку андроида назад на других экранах, тогда также ее вызывают.

componentDidMount() {

    if (Platform.OS == "android") {
        BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);                           
  }
    this._setupGoogleSignin();           
    this._getUserDetails();
    const { navigate } = this.props.navigation;
    console.log("object url is", this.state.postsArray[0].url);

}

handleBackButton = () => {               
    Alert.alert(
        'Exit App',
        'Exiting the application?', [{
            text: 'Cancel',
            onPress: () => console.log('Cancel Pressed'),
            style: 'cancel'
        }, {
            text: 'OK',
            onPress: () => BackHandler.exitApp()
        }, ], {
            cancelable: false
        }
     )
     return true;
   }
componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
  }

Ответ 1

Если ваш HomeScreen все еще смонтирован при переходе на другие экраны или при отключении HomeScreen если вы не удалите EventListener, он все равно будет вызываться.

Вы должны очистить EventListener при навигации или размонтировании,

onButtonPress = () => {
  BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
  // then navigate
  navigate('NewScreen');
}

handleBackButton = () => {
 Alert.alert(
     'Exit App',
     'Exiting the application?', [{
         text: 'Cancel',
         onPress: () = > console.log('Cancel Pressed'),
         style: 'cancel'
     }, {
         text: 'OK',
         onPress: () = > BackHandler.exitApp()
     }, ], {
         cancelable: false
     }
  )
  return true;
} 

componentDidMount() {
  BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}

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

Ответ 2

Если вы не хотите, чтобы оповещение появлялось на другом компоненте/экране, а только на одном конкретном компоненте/экране, вы можете следовать этому.

import { withNavigationFocus } from 'react-navigation';

class TestComponent extends Component {
  componentWillMount() {
    BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
  }

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

  handleBackButton = () => {
    if (this.props.isFocused) {
      Alert.alert(
        'Exit App',
        'Exiting the application?',
        [
          {
            text: 'Cancel',
            onPress: () => console.log('Cancel Pressed'),
            style: 'cancel'
          },
          {
            text: 'OK',
            onPress: () => BackHandler.exitApp()
          }
        ],
        {
          cancelable: false
        }
      );
      return true;
    }
  };
} 

export default withNavigationFocus(TestComponent );

BackHandler, который будет показывать предупреждающее сообщение, будет работать только в TestComponent

Ответ 3

Мы можем добавить подписки для didfocus в нашем главном контейнере приложений. Мы можем добавить нашу логику для проверки нажатия кнопки со статической переменной.

import {  Alert,  BackHandler,  ToastAndroid } from 'react-native';
import {  StackActions } from 'react-navigation';
import { Toast } from 'native-base';
// common statless class variable.
let backHandlerClickCount = 0;

class App extends React.Component {
    constructor(props) {
      super(props);
      // add listener to didFocus
      this._didFocusSubscription = props.navigation.addListener('didFocus', payload =>
        BackHandler.addEventListener('hardwareBackPress', () => this.onBackButtonPressAndroid(payload)));
    }

    // remove listener on unmount 
    componentWillUnmount() {
      if (this._didFocusSubscription) {
        this._didFocusSubscription.remove();
      }
    }

    onBackButtonPressAndroid = () => {
      const shortToast = message => {
        // ToastAndroid.showWithGravityAndOffset(
        //     message,
        //     ToastAndroid.SHORT,
        //     ToastAndroid.BOTTOM,
        //     25,
        //     50
        // );

        // ios & android
        Toast.show({
            text: message,
            type: 'warning',
            position: 'top',
            duration: 3000,
        });
        }

        const {
          clickedPosition
        } = this.state;
        backHandlerClickCount += 1;
        if ((clickedPosition !== 1)) {
          if ((backHandlerClickCount < 2)) {
            shortToast('Press again to quit the application!');
          } else {
            BackHandler.exitApp();
          }
        }

        // timeout for fade and exit
        setTimeout(() => {
          backHandlerClickCount = 0;
        }, 2000);

        if (((clickedPosition === 1) &&
            (this.props.navigation.isFocused()))) {
          Alert.alert(
            'Exit Application',
            'Do you want to quit application?', [{
              text: 'Cancel',
              onPress: () => console.log('Cancel Pressed'),
              style: 'cancel'
            }, {
              text: 'OK',
              onPress: () => BackHandler.exitApp()
            }], {
              cancelable: false
            }
          );
        } else {
          this.props.navigation.dispatch(StackActions.pop({
            n: 1
          }));
        }
        return true;
      }

    }

Ответ 4

Гайз, пожалуйста, поймите, это может быть не только проблема с реагировать на родной. Будьте осторожны при интеграции его с Firebase. В последней версии Firebase есть проблема интеграции кнопки "Назад" в приложения, реагирующие на естественное поведение! Пожалуйста, уменьшите версию firebase до firebase-version @5.0.3, а затем перепроверьте, работает она или нет! У меня была та же проблема, и я волновался несколько дней. Я наконец-то опустился до версии @5.0.3 и теперь кнопка возврата работает отлично! Вы можете перейти на более ранние версии, если проблема все еще остается.

Ответ 5

BackHandler.addEventListener('hardwareBackPress', function() {
    Alert.alert(
      'Thoát Khỏi Ứng Dụng',
      'Bạn có muốn thoát không?', [{
          text: 'Cancel',
          onPress: () => console.log('Cancel Pressed'),
          style: 'cancel'
      }, {
          text: 'OK',
          onPress: () => BackHandler.exitApp()
      }, ], {
          cancelable: false
      }
   )
   return true;
})

Ответ 6

Вы всегда можете динамически изменить то, что функция обратного вызова для BackHandler.addEventListener основана на текущей сцене (с react-native-router-flux это легко сделать).

import { Actions } from 'react-native-router-flux'

handleBackPress = () => {
 switch (Actions.currentScene) {
   case 'home':
     BackHandler.exitApp()
     break

   default: Actions.pop()
 }

 return true
}

Полный текст статьи можно найти здесь: https://gist.github.com/omeileo/f05a068557e9f0a2d8a24ecccd2f3177.