在React Native中,Android的应用在按下返回键退出?

3
在安卓小米Note 3上,硬件返回按钮不能触发handleBackPress,当我点击返回键时,应用程序会退出。
我已经尝试了以下代码,但handleBackPress没有被调用。
 componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
  }

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

  handleBackPress = () => {
    this.goBack(); // works best when the goBack is async
    return true;
  }

导航代码:
const ModalSignUp = createStackNavigator(
  {
    Signup: { screen: Signup, key: 'Signup' },
    PartyList: { screen: PartyList, key: 'PartyList' },
    StatesList: { screen: StatesList, key: 'StatesList' },

  },
  {
    initialRouteName: 'Signup',
    headerMode: 'none',
    mode: 'card',
  }
);

导航:

this.props.navigation.push("StatesList")

预期结果:

点击硬件按钮返回上一个屏幕。


你想禁用硬件返回按钮功能吗? - Piyush Govil
1
你在其他手机上测试过吗?这只发生在小米Note 3上还是其他手机也有这个问题? - Vencovsky
使用react-navigation时,你无法返回吗? - Vinil Prabhu
是的,我使用React Navigation。在旧版本中它是可以工作的,在我最老的应用程序中也很好。 - Kirit Modi
你正在使用哪个版本的react-navigation? - Vencovsky
显示剩余4条评论
5个回答

3

你的错误可能在获取下一个react-navigation视图的方式上。

你需要使用.push在堆栈中创建一个新视图,当你点击后退按钮时,.goBack()将会被触发。

默认情况下,后退按钮将总是使导航返回到堆栈上,但如果堆栈中只有一个视图(当你只使用.navigate时会发生这种情况),应用程序将退出。

不确定你是如何浏览视图的,但这可以是一个解决方案。

编辑:为了解决这个问题,在浏览视图时,请使用 navigation.push('viewname') 而不是 navigation.navigate('viewname')。你不需要任何其他方法(就像你在问题中提到的那个方法)。

还可以查看文档以了解导航工作原理或者这个问题


在stacknavigation中有四个视图,我将导航到最后一个视图。我也添加了所有视图的返回按钮。其中包括goBack()函数的实现。因此,设计上的返回是正确的。但是,如果点击硬件返回键,应用程序会退出。 - Kirit Modi
导航被用于。 - Kirit Modi
@KiritModi请检查我的答案,如果你想回到后退按钮,请使用.push()而不是.navigate(),这就是为什么应用程序退出而不是返回到上一个视图的原因。 - Vencovsky
请显示您更改的内容,以及您在视图中导航的位置。 - Vencovsky
1
谢谢帮忙,终于找到了解决方案。我会回答它的。 - Kirit Modi
显示剩余3条评论

2
尝试使用return false代替return true。最初的回答。

如果你已经很好地处理了事件,这在某些情况下是有效的。 - Charles

1

1. 导入

import { BackHandler, DeviceEventEmitter } from 'react-native'

2. 构造函数

constructor(props) {
    super(props)
    this.backPressSubscriptions = new Set()
  }

3. 添加和移除监听器

componentDidMount() {
    DeviceEventEmitter.removeAllListeners('hardwareBackPress')
    DeviceEventEmitter.addListener('hardwareBackPress', () => {
        let invokeDefault = true
        const subscriptions = []

        this.backPressSubscriptions.forEach(sub => subscriptions.push(sub))

        for (let i = 0; i < subscriptions.reverse().length; i += 1) {
            if (subscriptions[i]()) {
                invokeDefault = false
                break
            }
        }

        if (invokeDefault) {
            BackHandler.exitApp()
        }
    })

    this.backPressSubscriptions.add(this.handleHardwareBack)
}

componentWillUnmount() {
    DeviceEventEmitter.removeAllListeners('hardwareBackPress')
    this.backPressSubscriptions.clear()
}

处理返回键。
handleHardwareBack = () => {
    this.props.navigation.goBack(null)
    console.log(" ********** This is called ************ ");
    return true;
}

如果您在所有视图中使用.push(),我认为您不需要这样做。我有一个使用react-navigation的应用程序,它可以按照您想要的方式工作,而无需执行此操作。您说它在所有设备上都会发生,但我认为这只是在特定设备上出现的问题。 - Vencovsky

0

试试这个:

import {BackHandler} from 'react-native';

export default class Component extends Component {
     _didFocusSubscription;
     _willBlurSubscription;
     constructor(props) {
         super(props);
         this._didFocusSubscription = props.navigation.addListener('didFocus',payload =>
            BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
         ); 
     }
  }
componentDidMount() {
        this._willBlurSubscription = this.props.navigation.addListener('willBlur', payload =>
            BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
        );
 }
componentWillUnmount() {
        this._didFocusSubscription && this._didFocusSubscription.remove();
        this._willBlurSubscription && this._willBlurSubscription.remove();
    }
onBackButtonPressAndroid = () => {
    //code when you press the back button
 };

是的,我也从react-navigation代码中尝试了同样的方法,但还是不起作用。 - Kirit Modi

0

试试这个... 这个对我有效:在 componentWillUnmount 中。

BackHandler.removeEventListener('hardwareBackPress', () => {});

此外,在每种情况下,请确保检查您的 this.goBack(); 中是否返回了内容。
goback = () => {
   if (condition2) 
     // handling
    return something;

  if (condition2)
   // handling
   return something;

  // default:
  return true;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接