React Native之hardwareBackPress

举报
chenyu 发表于 2021/07/26 22:59:13 2021/07/26
【摘要】 1  hardwareBackPress 我们用hardwareBackPress来监听手机物理返回键         2 js那边常用写法 BackHandler.addEventListener('hardwareBackPress', this._back);      ...

1  hardwareBackPress

我们用hardwareBackPress来监听手机物理返回键

 

 

 

 

2 js那边常用写法

BackHandler.addEventListener('hardwareBackPress', this._back);
 

 

 

 

3  我们看下Android源代码分析是怎么触发到这里来的

1) ReactActivity.java里面的部分代码如下


  
  1. @Override
  2. public void onBackPressed() {
  3. if (!mDelegate.onBackPressed()) {
  4. super.onBackPressed();
  5. }
  6. }

2 ) 进入onBackPressed()函数看看,在ReactActivityDelegate.java文件里面


  
  1. public boolean onBackPressed() {
  2. if (getReactNativeHost().hasInstance()) {
  3. getReactNativeHost().getReactInstanceManager().onBackPressed();
  4. return true;
  5. }
  6. return false;
  7. }

3)再次点击onBackPressed函数进去看下


  
  1. public void onBackPressed() {
  2. UiThreadUtil.assertOnUiThread();
  3. ReactContext reactContext = mCurrentReactContext;
  4. if (reactContext == null) {
  5. // Invoke without round trip to JS.
  6. FLog.w(ReactConstants.TAG, "Instance detached from instance manager");
  7. invokeDefaultOnBackPressed();
  8. } else {
  9. DeviceEventManagerModule deviceEventManagerModule =
  10. reactContext.getNativeModule(DeviceEventManagerModule.class);
  11. deviceEventManagerModule.emitHardwareBackPressed();
  12. }
  13. }

4) 进到emitHardwareBackPressed函数里面看下


  
  1. /**
  2. * Sends an event to the JS instance that the hardware back has been pressed.
  3. */
  4. public void emitHardwareBackPressed() {
  5. getReactApplicationContext()
  6. .getJSModule(RCTDeviceEventEmitter.class)
  7. .emit("hardwareBackPress", null);
  8. }

这里发现了Android原生向js发送了消息,所以我们监听hardwareBackPress就有反映

 

 

 

 

 

 

4 测试代码如下

App.js文件如下


  
  1. import React from 'react';
  2. import { View, Text, Button, NativeModules, BackHandler} from 'react-native';
  3. import { createStackNavigator } from 'react-navigation';
  4. var toast = NativeModules.MyToast;
  5. class HomeScreen extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. console.log("HomeScreen constructor start");
  9. }
  10. static navigationOptions = {
  11. title : 'HomeScreen',
  12. }
  13. componentDidMount = () => {
  14. this.didFocusListener = this.props.navigation.addListener(
  15. 'didFocus',
  16. (obj) => {
  17. console.log("HomeScreen didFocus start");
  18. BackHandler.addEventListener('hardwareBackPress', this._back);
  19. }
  20. );
  21. this.didBlurListener = this.props.navigation.addListener(
  22. 'didBlur',
  23. (obj) => {console.log('HomeScreen didBlur start')}
  24. );
  25. console.log("HomeScreen componentDidMount start")
  26. }
  27. componentWillUnmount() {
  28. console.log("HomeScreen componentWillUnmount start")
  29. this.didFocusListener.remove();
  30. this.didBlurListener.remove();
  31. }
  32. render() {
  33. var testID = 'chenyu';
  34. return (
  35. <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
  36. <Text testID = {testID} onPress = {() => this._goto()}>Home Screen</Text>
  37. <Button onPress={() => this.props.navigation.navigate('Details', {
  38. itemId:100,
  39. otherParam:'chenyu',
  40. })} title = "go to Details"/>
  41. <Button
  42. title="Go back"
  43. onPress={() => this.props.navigation.goBack()}
  44. />
  45. </View>
  46. );
  47. }
  48. _show(value) {
  49. console.log(value);
  50. }
  51. _goto = () => {
  52. toast.show();
  53. }
  54. _back = () => {
  55. console.log("home back");
  56. }
  57. }
  58. class DetailsScreen extends React.Component {
  59. constructor(props) {
  60. super(props);
  61. console.log("DetailsScreen constructor start");
  62. this.didFocusListener = this.props.navigation.addListener(
  63. 'didFocus',
  64. (obj) => {
  65. console.log("DetailsScreen didFocus start");
  66. BackHandler.addEventListener('hardwareBackPress', this._back);
  67. }
  68. );
  69. this.didBlurListener = this.props.navigation.addListener(
  70. 'didBlur',
  71. (obj) => {console.log('DetailsScreen didBlur start')}
  72. );
  73. }
  74. _back = () => {
  75. console.log("detail back");
  76. }
  77. static navigationOptions = ({navigation}) => {
  78. return {
  79. title : navigation.getParam('otherParam', 'no-values'),
  80. };
  81. };
  82. componentDidMount = () => {
  83. console.log("DetailsScreen componentDidMount start")
  84. }
  85. componentWillUnmount() {
  86. console.log("DetailsScreen componentWillUnmount start")
  87. this.didFocusListener.remove();
  88. this.didBlurListener.remove();
  89. }
  90. render() {
  91. const {navigation} = this.props;
  92. const itemId = navigation.getParam('itemId', 'no-values');
  93. const otherParam = navigation.getParam('otherParam', 'no-values');
  94. return (
  95. <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  96. <Text>Details Screen</Text>
  97. <Text>itemId:{JSON.stringify(itemId)}</Text>
  98. <Text>otherParam:{JSON.stringify(otherParam)}</Text>
  99. <Button
  100. title="Go to Details... again"
  101. onPress={() => this.props.navigation.push('Details', {
  102. itemId: Math.floor(Math.random() * 100),
  103. })}
  104. />
  105. <Button
  106. title="Go to Home"
  107. onPress={() => this.props.navigation.navigate('Home')}
  108. />
  109. <Button
  110. title="Go back"
  111. onPress={() => this.props.navigation.goBack()}
  112. />
  113. <Button
  114. title="Go popToTop"
  115. onPress={() => this.props.navigation.popToTop()}
  116. />
  117. </View>
  118. );
  119. }
  120. }
  121. const RootStack = createStackNavigator(
  122. {
  123. Home: HomeScreen,
  124. Details: DetailsScreen,
  125. },
  126. {
  127. initialRouteName: 'Home',
  128. }
  129. );
  130. export default class App extends React.Component {
  131. constructor(props) {
  132. super(props);
  133. }
  134. render() {
  135. return <RootStack/>;
  136. }
  137. }

 

 

 

 

 

 

5 运行结果

点击主界面的GO TO DETAILS,进入详细页面,然后分别按下2次back键,日志如下


  
  1. 10-27 23:39:32.498 917 1031 I ReactNativeJS: detail back
  2. 10-27 23:39:32.498 917 1031 I ReactNativeJS: home back
  3. 10-27 23:39:32.784 917 1031 I ReactNativeJS: DetailsScreen componentWillUnmount start
  4. 10-27 23:39:32.790 917 1031 I ReactNativeJS: HomeScreen didFocus start
  5. 10-27 23:39:51.164 917 1031 I ReactNativeJS: detail back
  6. 10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
  7. 10-27 23:39:51.165 917 1031 I ReactNativeJS: detail back
  8. 10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
  9. 10-27 23:39:51.165 917 1031 I ReactNativeJS: detail back
  10. 10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
  11. 10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
  12. 10-27 23:39:51.165 917 1031 I ReactNativeJS: detail back
  13. 10-27 23:39:51.166 917 1031 I ReactNativeJS: detail back
  14. 10-27 23:39:51.166 917 1031 I ReactNativeJS: home back
  15. 10-27 23:39:51.166 917 1031 I ReactNativeJS: detail back
  16. 10-27 23:39:51.166 917 1031 I ReactNativeJS: home back
  17. 10-27 23:39:51.166 917 1031 I ReactNativeJS: home back
  18. 10-27 23:39:51.621 917 1031 I ReactNativeJS: HomeScreen componentWillUnmount start

我们点击标题栏的返回按钮,和点击GO BACK,执行this.props.navigation.goBack()方法,都不会触发hardwareBackPress监听所执行的函数

 

文章来源: chenyu.blog.csdn.net,作者:chen.yu,版权归原作者所有,如需转载,请联系作者。

原文链接:chenyu.blog.csdn.net/article/details/83388372

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。