react-native-navigation的迁移库

Navigator.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package com.reactnativenavigation.viewcontrollers.navigator;
  2. import android.app.Activity;
  3. import android.view.ViewGroup;
  4. import com.facebook.react.ReactInstanceManager;
  5. import com.reactnativenavigation.parse.Options;
  6. import com.reactnativenavigation.presentation.OverlayManager;
  7. import com.reactnativenavigation.presentation.Presenter;
  8. import com.reactnativenavigation.presentation.RootPresenter;
  9. import com.reactnativenavigation.react.events.EventEmitter;
  10. import com.reactnativenavigation.utils.CommandListener;
  11. import com.reactnativenavigation.utils.CommandListenerAdapter;
  12. import com.reactnativenavigation.utils.CompatUtils;
  13. import com.reactnativenavigation.utils.Functions.Func1;
  14. import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
  15. import com.reactnativenavigation.viewcontrollers.ParentController;
  16. import com.reactnativenavigation.viewcontrollers.ViewController;
  17. import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
  18. import com.reactnativenavigation.viewcontrollers.stack.StackController;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.List;
  22. import androidx.annotation.NonNull;
  23. import androidx.annotation.Nullable;
  24. import androidx.annotation.RestrictTo;
  25. import androidx.coordinatorlayout.widget.CoordinatorLayout;
  26. public class Navigator extends ParentController {
  27. private final ModalStack modalStack;
  28. private final OverlayManager overlayManager;
  29. private final RootPresenter rootPresenter;
  30. private ViewController root;
  31. private ViewController previousRoot;
  32. private final CoordinatorLayout rootLayout;
  33. private final CoordinatorLayout modalsLayout;
  34. private final CoordinatorLayout overlaysLayout;
  35. private ViewGroup contentLayout;
  36. private Options defaultOptions = new Options();
  37. @Override
  38. public void setDefaultOptions(Options defaultOptions) {
  39. super.setDefaultOptions(defaultOptions);
  40. this.defaultOptions = defaultOptions;
  41. modalStack.setDefaultOptions(defaultOptions);
  42. }
  43. public Options getDefaultOptions() {
  44. return defaultOptions;
  45. }
  46. CoordinatorLayout getRootLayout() {
  47. return rootLayout;
  48. }
  49. public void setEventEmitter(EventEmitter eventEmitter) {
  50. modalStack.setEventEmitter(eventEmitter);
  51. }
  52. public void setContentLayout(ViewGroup contentLayout) {
  53. this.contentLayout = contentLayout;
  54. contentLayout.addView(rootLayout);
  55. contentLayout.addView(modalsLayout);
  56. }
  57. public Navigator(final Activity activity, ChildControllersRegistry childRegistry, ModalStack modalStack, OverlayManager overlayManager, RootPresenter rootPresenter) {
  58. super(activity, childRegistry,"navigator" + CompatUtils.generateViewId(), new Presenter(activity, new Options()), new Options());
  59. this.modalStack = modalStack;
  60. this.overlayManager = overlayManager;
  61. this.rootPresenter = rootPresenter;
  62. rootLayout = new CoordinatorLayout(getActivity());
  63. modalsLayout = new CoordinatorLayout(getActivity());
  64. overlaysLayout = new CoordinatorLayout(getActivity());
  65. }
  66. public void bindViews() {
  67. modalStack.setModalsLayout(modalsLayout);
  68. modalStack.setRootLayout(rootLayout);
  69. rootPresenter.setRootContainer(rootLayout);
  70. }
  71. @NonNull
  72. @Override
  73. protected ViewGroup createView() {
  74. return rootLayout;
  75. }
  76. @NonNull
  77. @Override
  78. public Collection<ViewController> getChildControllers() {
  79. return root == null ? Collections.emptyList() : Collections.singletonList(root);
  80. }
  81. @Override
  82. public boolean handleBack(CommandListener listener) {
  83. if (modalStack.isEmpty() && root == null) return false;
  84. if (modalStack.isEmpty()) return root.handleBack(listener);
  85. return modalStack.handleBack(listener, root);
  86. }
  87. @Override
  88. protected ViewController getCurrentChild() {
  89. return root;
  90. }
  91. @Override
  92. public void destroy() {
  93. destroyViews();
  94. super.destroy();
  95. }
  96. public void destroyViews() {
  97. modalStack.destroy();
  98. overlayManager.destroy();
  99. destroyRoot();
  100. }
  101. private void destroyRoot() {
  102. if (root != null) root.destroy();
  103. root = null;
  104. }
  105. private void destroyPreviousRoot() {
  106. if (previousRoot != null) previousRoot.destroy();
  107. previousRoot = null;
  108. }
  109. @Override
  110. public void sendOnNavigationButtonPressed(String buttonId) {
  111. }
  112. public void setRoot(final ViewController viewController, CommandListener commandListener, ReactInstanceManager reactInstanceManager) {
  113. previousRoot = root;
  114. modalStack.destroy();
  115. final boolean removeSplashView = isRootNotCreated();
  116. if (isRootNotCreated()) getView();
  117. root = viewController;
  118. rootPresenter.setRoot(root, defaultOptions, new CommandListenerAdapter(commandListener) {
  119. @Override
  120. public void onSuccess(String childId) {
  121. if (removeSplashView) contentLayout.removeViewAt(0);
  122. super.onSuccess(childId);
  123. destroyPreviousRoot();
  124. }
  125. }, reactInstanceManager);
  126. }
  127. public void mergeOptions(final String componentId, Options options) {
  128. ViewController target = findController(componentId);
  129. if (target != null) {
  130. target.mergeOptions(options);
  131. }
  132. }
  133. public void push(final String id, final ViewController viewController, CommandListener listener) {
  134. applyOnStack(id, listener, stack -> stack.push(viewController, listener));
  135. }
  136. public void setStackRoot(String id, List<ViewController> children, CommandListener listener) {
  137. applyOnStack(id, listener, stack -> stack.setRoot(children, listener));
  138. }
  139. public void pop(String id, Options mergeOptions, CommandListener listener) {
  140. applyOnStack(id, listener, stack -> stack.pop(mergeOptions, listener));
  141. }
  142. public void popToRoot(final String id, Options mergeOptions, CommandListener listener) {
  143. applyOnStack(id, listener, stack -> stack.popToRoot(mergeOptions, listener));
  144. }
  145. public void popTo(final String id, Options mergeOptions, CommandListener listener) {
  146. ViewController target = findController(id);
  147. if (target != null) {
  148. target.performOnParentStack(stack -> ((StackController) stack).popTo(target, mergeOptions, listener));
  149. } else {
  150. listener.onError("Failed to execute stack command. Stack by " + id + " not found.");
  151. }
  152. }
  153. public void showModal(final ViewController viewController, CommandListener listener) {
  154. modalStack.showModal(viewController, root, listener);
  155. }
  156. public void dismissModal(final String componentId, CommandListener listener) {
  157. if (isRootNotCreated() && modalStack.size() == 1) {
  158. listener.onError("Can not dismiss modal if root is not set and only one modal is displayed.");
  159. return;
  160. }
  161. modalStack.dismissModal(componentId, root, listener);
  162. }
  163. public void dismissAllModals(Options mergeOptions, CommandListener listener) {
  164. modalStack.dismissAllModals(root, mergeOptions, listener);
  165. }
  166. public void showOverlay(ViewController overlay, CommandListener listener) {
  167. overlayManager.show(contentLayout, overlaysLayout, overlay, listener);
  168. }
  169. public void dismissOverlay(final String componentId, CommandListener listener) {
  170. overlayManager.dismiss(componentId, listener);
  171. }
  172. @Nullable
  173. @Override
  174. public ViewController findController(String id) {
  175. ViewController controllerById = super.findController(id);
  176. if (controllerById == null) {
  177. controllerById = modalStack.findControllerById(id);
  178. }
  179. if (controllerById == null) {
  180. controllerById = overlayManager.findControllerById(id);
  181. }
  182. return controllerById;
  183. }
  184. private void applyOnStack(String fromId, CommandListener listener, Func1<StackController> task) {
  185. ViewController from = findController(fromId);
  186. if (from != null) {
  187. if (from instanceof StackController) {
  188. task.run((StackController) from);
  189. } else {
  190. from.performOnParentStack(stack -> task.run((StackController) stack) );
  191. }
  192. } else {
  193. listener.onError("Failed to execute stack command. Stack " + fromId + " not found.");
  194. }
  195. }
  196. private boolean isRootNotCreated() {
  197. return view == null;
  198. }
  199. @RestrictTo(RestrictTo.Scope.TESTS)
  200. CoordinatorLayout getModalsLayout() {
  201. return modalsLayout;
  202. }
  203. }