react-native-navigation的迁移库

ScreenStack.java 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package com.reactnativenavigation.screens;
  2. import android.support.annotation.Nullable;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.view.View;
  5. import android.widget.RelativeLayout;
  6. import com.reactnativenavigation.NavigationApplication;
  7. import com.reactnativenavigation.params.ScreenParams;
  8. import com.reactnativenavigation.params.StyleParams;
  9. import com.reactnativenavigation.params.TitleBarButtonParams;
  10. import com.reactnativenavigation.params.TitleBarLeftButtonParams;
  11. import com.reactnativenavigation.utils.KeyboardVisibilityDetector;
  12. import com.reactnativenavigation.utils.Task;
  13. import com.reactnativenavigation.views.LeftButtonOnClickListener;
  14. import java.util.List;
  15. import java.util.Stack;
  16. public class ScreenStack {
  17. public interface OnScreenPop {
  18. void onScreenPopAnimationEnd();
  19. }
  20. private final AppCompatActivity activity;
  21. private RelativeLayout parent;
  22. private LeftButtonOnClickListener leftButtonOnClickListener;
  23. private Stack<Screen> stack = new Stack<>();
  24. private final KeyboardVisibilityDetector keyboardVisibilityDetector;
  25. private boolean isStackVisible = false;
  26. private final String navigatorId;
  27. public String getNavigatorId() {
  28. return navigatorId;
  29. }
  30. public ScreenStack(AppCompatActivity activity,
  31. RelativeLayout parent,
  32. String navigatorId,
  33. LeftButtonOnClickListener leftButtonOnClickListener) {
  34. this.activity = activity;
  35. this.parent = parent;
  36. this.navigatorId = navigatorId;
  37. this.leftButtonOnClickListener = leftButtonOnClickListener;
  38. keyboardVisibilityDetector = new KeyboardVisibilityDetector(parent);
  39. }
  40. public void pushInitialScreen(ScreenParams initialScreenParams, RelativeLayout.LayoutParams params) {
  41. Screen initialScreen = ScreenFactory.create(activity, initialScreenParams, leftButtonOnClickListener);
  42. initialScreen.setVisibility(View.INVISIBLE);
  43. addScreen(initialScreen, params);
  44. }
  45. public void push(final ScreenParams params, RelativeLayout.LayoutParams layoutParams) {
  46. Screen nextScreen = ScreenFactory.create(activity, params, leftButtonOnClickListener);
  47. final Screen previousScreen = stack.peek();
  48. if (isStackVisible) {
  49. pushScreenToVisibleStack(params, layoutParams, nextScreen, previousScreen);
  50. } else {
  51. pushScreenToInvisibleStack(layoutParams, nextScreen, previousScreen);
  52. }
  53. }
  54. private void pushScreenToVisibleStack(final ScreenParams params, RelativeLayout.LayoutParams layoutParams,
  55. final Screen nextScreen, final Screen previousScreen) {
  56. nextScreen.setVisibility(View.INVISIBLE);
  57. addScreen(nextScreen, layoutParams);
  58. nextScreen.setOnDisplayListener(new Screen.OnDisplayListener() {
  59. @Override
  60. public void onDisplay() {
  61. nextScreen.show(params.animateScreenTransitions, new Runnable() {
  62. @Override
  63. public void run() {
  64. removePreviousWithoutUnmount(previousScreen);
  65. }
  66. });
  67. }
  68. });
  69. }
  70. private void pushScreenToInvisibleStack(RelativeLayout.LayoutParams layoutParams, Screen nextScreen,
  71. Screen previousScreen) {
  72. nextScreen.setVisibility(View.INVISIBLE);
  73. addScreen(nextScreen, layoutParams);
  74. removePreviousWithoutUnmount(previousScreen);
  75. }
  76. private void addScreen(Screen screen, RelativeLayout.LayoutParams layoutParams) {
  77. parent.addView(screen, layoutParams);
  78. stack.push(screen);
  79. }
  80. private void removePreviousWithoutUnmount(Screen previous) {
  81. previous.preventUnmountOnDetachedFromWindow();
  82. parent.removeView(previous);
  83. }
  84. public void pop(boolean animated) {
  85. pop(animated, null);
  86. }
  87. public void pop(final boolean animated, @Nullable final OnScreenPop onScreenPop) {
  88. if (!canPop()) {
  89. return;
  90. }
  91. final Screen toRemove = stack.pop();
  92. final Screen previous = stack.peek();
  93. if (keyboardVisibilityDetector.isKeyboardVisible()) {
  94. keyboardVisibilityDetector.closeKeyboard(new Runnable() {
  95. @Override
  96. public void run() {
  97. swapScreens(animated, toRemove, previous, onScreenPop);
  98. }
  99. });
  100. } else {
  101. swapScreens(animated, toRemove, previous, onScreenPop);
  102. }
  103. }
  104. private void swapScreens(boolean animated, final Screen toRemove, Screen previous, OnScreenPop onScreenPop) {
  105. readdPrevious(previous);
  106. previous.setStyle();
  107. toRemove.hide(animated, new Runnable() {
  108. @Override
  109. public void run() {
  110. toRemove.ensureUnmountOnDetachedFromWindow();
  111. parent.removeView(toRemove);
  112. }
  113. });
  114. if (onScreenPop != null) {
  115. onScreenPop.onScreenPopAnimationEnd();
  116. }
  117. }
  118. public Screen peek() {
  119. return stack.peek();
  120. }
  121. private void readdPrevious(Screen previous) {
  122. previous.setVisibility(View.VISIBLE);
  123. parent.addView(previous, 0);
  124. previous.preventMountAfterReattachedToWindow();
  125. }
  126. public void popToRoot(boolean animated) {
  127. while (canPop()) {
  128. pop(animated);
  129. }
  130. }
  131. public void destroy() {
  132. for (Screen screen : stack) {
  133. screen.ensureUnmountOnDetachedFromWindow();
  134. parent.removeView(screen);
  135. }
  136. stack.clear();
  137. }
  138. public int getStackSize() {
  139. return stack.size();
  140. }
  141. public boolean canPop() {
  142. return getStackSize() > 1;
  143. }
  144. public void setScreenTopBarVisible(String screenInstanceId, final boolean visible, final boolean animate) {
  145. performOnScreen(screenInstanceId, new Task<Screen>() {
  146. @Override
  147. public void run(Screen param) {
  148. param.setTopBarVisible(visible, animate);
  149. }
  150. });
  151. }
  152. public void setScreenTitleBarTitle(String screenInstanceId, final String title) {
  153. performOnScreen(screenInstanceId, new Task<Screen>() {
  154. @Override
  155. public void run(Screen param) {
  156. param.setTitleBarTitle(title);
  157. }
  158. });
  159. }
  160. public void setScreenTitleBarRightButtons(String screenInstanceId, final String navigatorEventId, final List<TitleBarButtonParams> titleBarButtons) {
  161. performOnScreen(screenInstanceId, new Task<Screen>() {
  162. @Override
  163. public void run(Screen param) {
  164. param.setTitleBarRightButtons(navigatorEventId, titleBarButtons);
  165. }
  166. });
  167. }
  168. public void setScreenTitleBarLeftButton(String screenInstanceId, final String navigatorEventId, final TitleBarLeftButtonParams titleBarLeftButtonParams) {
  169. performOnScreen(screenInstanceId, new Task<Screen>() {
  170. @Override
  171. public void run(Screen param) {
  172. param.setTitleBarLeftButton(navigatorEventId, leftButtonOnClickListener, titleBarLeftButtonParams);
  173. }
  174. });
  175. }
  176. public StyleParams getCurrentScreenStyleParams() {
  177. return stack.peek().getStyleParams();
  178. }
  179. public boolean handleBackPressInJs() {
  180. ScreenParams currentScreen = stack.peek().screenParams;
  181. if (currentScreen.overrideBackPressInJs) {
  182. NavigationApplication.instance.sendNavigatorEvent("backPress", currentScreen.navigatorEventId);
  183. return true;
  184. }
  185. return false;
  186. }
  187. private void performOnScreen(String screenInstanceId, Task<Screen> task) {
  188. if (stack.isEmpty()) {
  189. return;
  190. }
  191. for (Screen screen : stack) {
  192. if (screen.getScreenInstanceId().equals(screenInstanceId)) {
  193. task.run(screen);
  194. return;
  195. }
  196. }
  197. }
  198. public void show() {
  199. isStackVisible = true;
  200. stack.peek().setStyle();
  201. stack.peek().setVisibility(View.VISIBLE);
  202. }
  203. public void hide() {
  204. isStackVisible = false;
  205. stack.peek().setVisibility(View.INVISIBLE);
  206. }
  207. }