BackHandler.android.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow
  8. * @format
  9. */
  10. 'use strict';
  11. import NativeDeviceEventManager from '../../Libraries/NativeModules/specs/NativeDeviceEventManager';
  12. import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
  13. const DEVICE_BACK_EVENT = 'hardwareBackPress';
  14. type BackPressEventName = 'backPress' | 'hardwareBackPress';
  15. const _backPressSubscriptions = [];
  16. RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() {
  17. for (let i = _backPressSubscriptions.length - 1; i >= 0; i--) {
  18. if (_backPressSubscriptions[i]()) {
  19. return;
  20. }
  21. }
  22. BackHandler.exitApp();
  23. });
  24. /**
  25. * Detect hardware button presses for back navigation.
  26. *
  27. * Android: Detect hardware back button presses, and programmatically invoke the default back button
  28. * functionality to exit the app if there are no listeners or if none of the listeners return true.
  29. *
  30. * tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented:
  31. * programmatically disable menu button handling
  32. * functionality to exit the app if there are no listeners or if none of the listeners return true.)
  33. *
  34. * iOS: Not applicable.
  35. *
  36. * The event subscriptions are called in reverse order (i.e. last registered subscription first),
  37. * and if one subscription returns true then subscriptions registered earlier will not be called.
  38. *
  39. * Example:
  40. *
  41. * ```javascript
  42. * BackHandler.addEventListener('hardwareBackPress', function() {
  43. * // this.onMainScreen and this.goBack are just examples, you need to use your own implementation here
  44. * // Typically you would use the navigator here to go to the last state.
  45. *
  46. * if (!this.onMainScreen()) {
  47. * this.goBack();
  48. * return true;
  49. * }
  50. * return false;
  51. * });
  52. * ```
  53. */
  54. type TBackHandler = {|
  55. +exitApp: () => void,
  56. +addEventListener: (
  57. eventName: BackPressEventName,
  58. handler: Function,
  59. ) => {remove: () => void, ...},
  60. +removeEventListener: (
  61. eventName: BackPressEventName,
  62. handler: Function,
  63. ) => void,
  64. |};
  65. const BackHandler: TBackHandler = {
  66. exitApp: function(): void {
  67. if (!NativeDeviceEventManager) {
  68. return;
  69. }
  70. NativeDeviceEventManager.invokeDefaultBackPressHandler();
  71. },
  72. /**
  73. * Adds an event handler. Supported events:
  74. *
  75. * - `hardwareBackPress`: Fires when the Android hardware back button is pressed or when the
  76. * tvOS menu button is pressed.
  77. */
  78. addEventListener: function(
  79. eventName: BackPressEventName,
  80. handler: Function,
  81. ): {remove: () => void, ...} {
  82. if (_backPressSubscriptions.indexOf(handler) === -1) {
  83. _backPressSubscriptions.push(handler);
  84. }
  85. return {
  86. remove: (): void => BackHandler.removeEventListener(eventName, handler),
  87. };
  88. },
  89. /**
  90. * Removes the event handler.
  91. */
  92. removeEventListener: function(
  93. eventName: BackPressEventName,
  94. handler: Function,
  95. ): void {
  96. if (_backPressSubscriptions.indexOf(handler) !== -1) {
  97. _backPressSubscriptions.splice(
  98. _backPressSubscriptions.indexOf(handler),
  99. 1,
  100. );
  101. }
  102. },
  103. };
  104. module.exports = BackHandler;