Как остановить работу аппаратной кнопки Android Back в react-navigation для react-native?


Я разрабатываю тривиальную игру, я использую react-navigation для управления навигацией, у меня есть 3 компонента (newGame, Questions, Results ) я не хочу, чтобы пользователь возвращался к вопросам со страницы результатов, если нет. количество вопросов было исчерпано, однако нажатие кнопки Назад (аппаратное обеспечение Android) возвращает его к вопросам. Затем я попытался обработать аппаратную кнопку Назад следующим образом:

componentWillMount() {
      this.props.gameState(true);
      BackHandler.addEventListener('hardwareBackPress', () => {
        if (this.props.gamePlaying) { // Currently set to true. I will set it to false again on NewGame Page.
          this.props.navigation.navigate('NewGame');
        }
      });
    }

Однако это приведет пользователя к экрану NewGame, но немедленно, он возвращается на страницу результатов, так как он запускает навигацию/назад, а также немедленно на странице NewGame. Что снова возвращает его на страницу результатов.

Возможно исправить?

Я хочу остановить кнопку "Назад" для запуска после того, как я приземлился на странице компонента NewGame. Есть ли способ сделать это?

Мое Окружение

React-navigation = ^1.0.0-beta.Одиннадцать react-native = 0.44.0

3 5

3 ответа:

Вам нужно вернуть true, чтобы указать, что вы сами обработали кнопку назад, как вы можете видеть в docs.

Если одна подписка возвращает true, то ранее зарегистрированные подписки не будут вызываться

Ваш код должен выглядеть следующим образом:

componentWillMount() {
    this.props.gameState(true);
    BackHandler.addEventListener('hardwareBackPress', () => {
        if (this.props.gamePlaying) {
            this.props.navigation.navigate('NewGame');
            return true; // This will prevent the regular handling of the back button
        }

        return false;
    });
}

Один из способов остановить работу кнопки-это ввести логику в ваш BackHandler eventlistener, когда вы его запускаете, например:

BackHandler.addEventListener('hardwareBackPress', () => {
    const { dispatch, nav } = this.props
    if (nav.routes.length === 1 && (nav.routes[0].routeName === 'Login' || nav.routes[0].routeName === 'Start')) return false
    dispatch({ type: 'Navigation/BACK' })
    return true
})
Обратите внимание, как мы наблюдаем условия. Ключом к этому вопросу является возврат true или false из прослушивателя событий. false останавливает работу аппаратной кнопки "Назад". true clean-выход из события.

Вот еще один пример для иллюстрации:

BackHandler.addEventListener('hardwareBackPress', () => {
    const { dispatch, nav } = this.props
    if (nav.routes[0].routeName === 'TriviaQuestion') return false
    if (!playTimeLeft && (nav.routes[0].routeName === 'TriviaQuestion')) return false
    if (nav.routes[0].routeName === 'InvasiveDialog') return false
    dispatch({ type: 'Navigation/BACK' })
    return true
})

Вот некоторые примеры кода, которые полезно посмотреть для получения дополнительной информации цели, чем просто остановить кнопку Назад от функционирования:

import React, { Component } from 'react'
import { Platform, BackHandler } from 'react-native'
import { Provider, connect } from 'react-redux'
import { addNavigationHelpers } from 'react-navigation'
import { NavigationStack } from './navigation/nav_reducer'
import store from './store'

class App extends Component {
    componentWillMount() {
        if (Platform.OS !== 'android') return
        BackHandler.addEventListener('hardwareBackPress', () => {
            const { dispatch, nav } = this.props
            if (nav.routes.length === 1 && (nav.routes[0].routeName === 'Login' || nav.routes[0].routeName === 'Start')) return false
            dispatch({ type: 'Navigation/BACK' })
            return true
        })
    }

    componentWillUnmount() {
        if (Platform.OS === 'android') BackHandler.removeEventListener('hardwareBackPress')
    }

    render() {
        const { dispatch, nav } = this.props
        const navigation = addNavigationHelpers({
            dispatch,
            state: nav
        })
        return <NavigationStack navigation={navigation} />
    }
}

const mapStateToProps = ({ nav }) => ({ nav })
const RootNavigationStack = connect(mapStateToProps)(App)

const Root = () => (
    <Provider store={store}>
        <RootNavigationStack />
    </Provider>
)

export default Root

Если вы нашли этот пост, пытаясь заставить кнопку "Назад" просто работать, просто скопируйте мой последний пример как можно ближе. Используйте прослушиватель событий точно так, как показано на рисунке, и сначала протестируйте приложение, чтобы увидеть, как оно работает.

Если вы используете Redux, это то, что вам нужно.

NavigationStack просто ссылается на export const NavigationStack = StackNavigator({ ...etc }) в другом файле.

Когда пользователь переключается между экранами в StackNavigator есть кнопка назад по умолчанию, мы можем исправить это, установив: headerLeft в null

static navigationOptions =({navigation}) => {
    return {
        title: 'Rechercher une ville',
        headerLeft: null,
    }  
}