【问题标题】:How to stop the Android Hardware Back Button from functioning in react-navigation for react-native?如何阻止 Android 硬件后退按钮在 react-native 的 react-navigation 中运行?
【发布时间】:2017-11-30 03:48:40
【问题描述】:

我正在开发一个琐事游戏,我正在使用 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 页面中触发 NAVIGATION/BACK。这再次将其带回结果页面。

可能的修复?

我想在登陆 NewGame 组件页面后停止后退按钮触发。有办法吗?

我的环境

反应导航 = ^1.0.0-beta.11 反应原生 = 0.44.0

【问题讨论】:

    标签: javascript react-native react-redux react-native-android react-navigation


    【解决方案1】:

    您需要返回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;
        });
    }
    

    【讨论】:

    • 非常感谢! :D 谢谢!!
    • 很遗憾,eventListener 没有被移除,组件也没有被卸载。
    【解决方案2】:

    阻止按钮运行的一种方法是在启动时将逻辑引入 BackHandler 事件侦听器,如下所示:

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

    注意我们是如何观察条件的。这个问题的关键是从事件监听器返回truefalsefalse 使硬件后退按钮停止工作。 true 干净退出事件。

    这里有另一个例子来说明:

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

    【讨论】:

      【解决方案3】:

      当用户在StackNavigator中切换屏幕时默认有一个返回按钮,我们可以通过设置:headerLeft为null来修复它

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

      【讨论】:

      • 这不会阻止 Android 硬件返回问题中描述的行为。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      • 2023-02-01
      相关资源
      最近更新 更多